// CreateTransferMemoryStorage(b8, u64, handle<copy>) -> object<nn::am::service::IStorage> public ResultCode CreateTransferMemoryStorage(ServiceCtx context) { bool unknown = context.RequestData.ReadBoolean(); long size = context.RequestData.ReadInt64(); int handle = context.Request.HandleDesc.ToCopy[0]; KTransferMemory transferMem = context.Process.HandleTable.GetObject <KTransferMemory>(handle); if (transferMem == null) { Logger.Warning?.Print(LogClass.ServiceAm, $"Invalid TransferMemory Handle: {handle:X}"); return(ResultCode.Success); // TODO: Find correct error code } var data = new byte[transferMem.Size]; transferMem.Creator.CpuMemory.Read(transferMem.Address, data); context.Device.System.KernelContext.Syscall.CloseHandle(handle); MakeObject(context, new IStorage(data)); return(ResultCode.Success); }
private KernelResult CreateTransferMemory(ulong address, ulong size, MemoryPermission permission, out int handle) { handle = 0; if (!PageAligned(address)) { return(KernelResult.InvalidAddress); } if (!PageAligned(size) || size == 0) { return(KernelResult.InvalidSize); } if (address + size <= address) { return(KernelResult.InvalidMemState); } if (permission > MemoryPermission.ReadAndWrite || permission == MemoryPermission.Write) { return(KernelResult.InvalidPermission); } KernelResult result = _process.MemoryManager.ReserveTransferMemory(address, size, permission); if (result != KernelResult.Success) { return(result); } KTransferMemory transferMemory = new KTransferMemory(address, size); return(_process.HandleTable.GenerateHandle(transferMemory, out handle)); }
private void SvcCreateTransferMemory(AThreadState ThreadState) { long Position = (long)ThreadState.X1; long Size = (long)ThreadState.X2; if (!PageAligned(Position)) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } if (!PageAligned(Size) || Size == 0) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Size 0x{Size:x16} is not page aligned or is zero!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } if ((ulong)(Position + Size) <= (ulong)Position) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return; } MemoryPermission Permission = (MemoryPermission)ThreadState.X3; if (Permission > MemoryPermission.ReadAndWrite || Permission == MemoryPermission.Write) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid permission {Permission}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidPermission); return; } Process.MemoryManager.ReserveTransferMemory(Position, Size, Permission); KTransferMemory TransferMemory = new KTransferMemory(Position, Size); int Handle = Process.HandleTable.OpenHandle(TransferMemory); ThreadState.X0 = 0; ThreadState.X1 = (ulong)Handle; }
// OpenAudioRenderer(nn::audio::detail::AudioRendererParameterInternal parameter, u64 workBufferSize, nn::applet::AppletResourceUserId appletResourceId, pid, handle<copy> workBuffer, handle<copy> processHandle) // -> object<nn::audio::detail::IAudioRenderer> public ResultCode OpenAudioRenderer(ServiceCtx context) { AudioRendererConfiguration parameter = context.RequestData.ReadStruct <AudioRendererConfiguration>(); ulong workBufferSize = context.RequestData.ReadUInt64(); ulong appletResourceUserId = context.RequestData.ReadUInt64(); KTransferMemory workBufferTransferMemory = context.Process.HandleTable.GetObject <KTransferMemory>(context.Request.HandleDesc.ToCopy[0]); uint processHandle = (uint)context.Request.HandleDesc.ToCopy[1]; ResultCode result = _impl.OpenAudioRenderer(context, out IAudioRenderer renderer, ref parameter, workBufferSize, appletResourceUserId, workBufferTransferMemory, processHandle); if (result == ResultCode.Success) { MakeObject(context, new AudioRendererServer(renderer)); } return(result); }
[CommandHipc(12)] // 2.0.0+ // CreateHandleStorage(u64, handle<copy>) -> object<nn::am::service::IStorage> public ResultCode CreateHandleStorage(ServiceCtx context) { long size = context.RequestData.ReadInt64(); int handle = context.Request.HandleDesc.ToCopy[0]; KTransferMemory transferMem = context.Process.HandleTable.GetObject <KTransferMemory>(handle); if (size <= 0) { return(ResultCode.ObjectInvalid); } byte[] data = new byte[transferMem.Size]; transferMem.Creator.CpuMemory.Read(transferMem.Address, data); context.Device.System.KernelContext.Syscall.CloseHandle(handle); MakeObject(context, new IStorage(data)); return(ResultCode.Success); }
public Horizon(Switch device) { KernelContext = new KernelContext( device, device.Memory, device.Configuration.MemoryConfiguration.ToKernelMemorySize(), device.Configuration.MemoryConfiguration.ToKernelMemoryArrange()); Device = device; State = new SystemStateMgr(); PerformanceState = new PerformanceState(); NfpDevices = new List <NfpDevice>(); // Note: This is not really correct, but with HLE of services, the only memory // region used that is used is Application, so we can use the other ones for anything. KMemoryRegionManager region = KernelContext.MemoryManager.MemoryRegions[(int)MemoryRegion.NvServices]; ulong hidPa = region.Address; ulong fontPa = region.Address + HidSize; ulong iirsPa = region.Address + HidSize + FontSize; ulong timePa = region.Address + HidSize + FontSize + IirsSize; ulong appletCaptureBufferPa = region.Address + HidSize + FontSize + IirsSize + TimeSize; KPageList hidPageList = new KPageList(); KPageList fontPageList = new KPageList(); KPageList iirsPageList = new KPageList(); KPageList timePageList = new KPageList(); KPageList appletCaptureBufferPageList = new KPageList(); hidPageList.AddRange(hidPa, HidSize / KPageTableBase.PageSize); fontPageList.AddRange(fontPa, FontSize / KPageTableBase.PageSize); iirsPageList.AddRange(iirsPa, IirsSize / KPageTableBase.PageSize); timePageList.AddRange(timePa, TimeSize / KPageTableBase.PageSize); appletCaptureBufferPageList.AddRange(appletCaptureBufferPa, AppletCaptureBufferSize / KPageTableBase.PageSize); var hidStorage = new SharedMemoryStorage(KernelContext, hidPageList); var fontStorage = new SharedMemoryStorage(KernelContext, fontPageList); var iirsStorage = new SharedMemoryStorage(KernelContext, iirsPageList); var timeStorage = new SharedMemoryStorage(KernelContext, timePageList); var appletCaptureBufferStorage = new SharedMemoryStorage(KernelContext, appletCaptureBufferPageList); HidStorage = hidStorage; HidSharedMem = new KSharedMemory(KernelContext, hidStorage, 0, 0, KMemoryPermission.Read); FontSharedMem = new KSharedMemory(KernelContext, fontStorage, 0, 0, KMemoryPermission.Read); IirsSharedMem = new KSharedMemory(KernelContext, iirsStorage, 0, 0, KMemoryPermission.Read); KSharedMemory timeSharedMemory = new KSharedMemory(KernelContext, timeStorage, 0, 0, KMemoryPermission.Read); TimeServiceManager.Instance.Initialize(device, this, timeSharedMemory, timeStorage, TimeSize); AppletCaptureBufferTransfer = new KTransferMemory(KernelContext, appletCaptureBufferStorage); AppletState = new AppletStateMgr(this); AppletState.SetFocus(true); Font = new SharedFontManager(device, fontStorage); VsyncEvent = new KEvent(KernelContext); DisplayResolutionChangeEvent = new KEvent(KernelContext); AccountManager = device.Configuration.AccountManager; ContentManager = device.Configuration.ContentManager; CaptureManager = new CaptureManager(device); // TODO: use set:sys (and get external clock source id from settings) // TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate. UInt128 clockSourceId = new UInt128(Guid.NewGuid().ToByteArray()); IRtcManager.GetExternalRtcValue(out ulong rtcValue); // We assume the rtc is system time. TimeSpanType systemTime = TimeSpanType.FromSeconds((long)rtcValue); // Configure and setup internal offset TimeSpanType internalOffset = TimeSpanType.FromSeconds(device.Configuration.SystemTimeOffset); TimeSpanType systemTimeOffset = new TimeSpanType(systemTime.NanoSeconds + internalOffset.NanoSeconds); if (systemTime.IsDaylightSavingTime() && !systemTimeOffset.IsDaylightSavingTime()) { internalOffset = internalOffset.AddSeconds(3600L); } else if (!systemTime.IsDaylightSavingTime() && systemTimeOffset.IsDaylightSavingTime()) { internalOffset = internalOffset.AddSeconds(-3600L); } internalOffset = new TimeSpanType(-internalOffset.NanoSeconds); // First init the standard steady clock TimeServiceManager.Instance.SetupStandardSteadyClock(null, clockSourceId, systemTime, internalOffset, TimeSpanType.Zero, false); TimeServiceManager.Instance.SetupStandardLocalSystemClock(null, new SystemClockContext(), systemTime.ToSeconds()); if (NxSettings.Settings.TryGetValue("time!standard_network_clock_sufficient_accuracy_minutes", out object standardNetworkClockSufficientAccuracyMinutes)) { TimeSpanType standardNetworkClockSufficientAccuracy = new TimeSpanType((int)standardNetworkClockSufficientAccuracyMinutes * 60000000000); // The network system clock needs a valid system clock, as such we setup this system clock using the local system clock. TimeServiceManager.Instance.StandardLocalSystemClock.GetClockContext(null, out SystemClockContext localSytemClockContext); TimeServiceManager.Instance.SetupStandardNetworkSystemClock(localSytemClockContext, standardNetworkClockSufficientAccuracy); } TimeServiceManager.Instance.SetupStandardUserSystemClock(null, false, SteadyClockTimePoint.GetRandom()); // FIXME: TimeZone shoud be init here but it's actually done in ContentManager TimeServiceManager.Instance.SetupEphemeralNetworkSystemClock(); DatabaseImpl.Instance.InitializeDatabase(device); HostSyncpoint = new NvHostSyncpt(device); SurfaceFlinger = new SurfaceFlinger(device); InitLibHacHorizon(); InitializeAudioRenderer(); }
public ResultCode OpenAudioRenderer(ServiceCtx context, out IAudioRenderer obj, ref AudioRendererConfiguration parameter, ulong workBufferSize, ulong appletResourceUserId, KTransferMemory workBufferTransferMemory, uint processHandle) { var memoryManager = context.Process.HandleTable.GetKProcess((int)processHandle).CpuMemory; ResultCode result = (ResultCode)_impl.OpenAudioRenderer(out AudioRenderSystem renderer, memoryManager, ref parameter, appletResourceUserId, workBufferTransferMemory.Address, workBufferTransferMemory.Size, processHandle); if (result == ResultCode.Success) { obj = new AudioRenderer.AudioRenderer(renderer); } else { obj = null; } return(result); }
public IDisplayController(ServiceCtx context) { _transferMem = context.Device.System.AppletCaptureBufferTransfer; }