private void WriteImpl(ulong va, ReadOnlySpan <byte> data) { try { AssertValidAddressAndSize(va, (ulong)data.Length); if (IsContiguousAndMapped(va, data.Length)) { data.CopyTo(_backingMemory.GetSpan(GetPhysicalAddressInternal(va), data.Length)); } else { int offset = 0, size; if ((va & PageMask) != 0) { ulong pa = GetPhysicalAddressInternal(va); size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size)); offset += size; } for (; offset < data.Length; offset += size) { ulong pa = GetPhysicalAddressInternal(va + (ulong)offset); size = Math.Min(data.Length - offset, PageSize); data.Slice(offset, size).CopyTo(_backingMemory.GetSpan(pa, size)); } } } catch (InvalidMemoryRegionException) { if (_invalidAccessHandler == null || !_invalidAccessHandler(va)) { throw; } } }
/// <summary> /// Writes data to CPU mapped memory. /// </summary> /// <param name="va">Virtual address to write the data into</param> /// <param name="data">Data to be written</param> private void WriteImpl(ulong va, ReadOnlySpan <byte> data) { if (IsContiguous(va, data.Length)) { data.CopyTo(_backingMemory.GetSpan(GetPhysicalAddressInternal(va), data.Length)); } else { int offset = 0, size; if ((va & PageMask) != 0) { ulong pa = GetPhysicalAddressInternal(va); size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size)); offset += size; } for (; offset < data.Length; offset += size) { ulong pa = GetPhysicalAddressInternal(va + (ulong)offset); size = Math.Min(data.Length - offset, PageSize); data.Slice(offset, size).CopyTo(_backingMemory.GetSpan(pa, size)); } } }
/// <inheritdoc/> public ReadOnlySpan <byte> GetSpan(ulong va, int size, bool tracked = false) { if (tracked) { SignalMemoryTracking(va, (ulong)size, write: false); } else { AssertMapped(va, (ulong)size); } return(_addressSpaceMirror.GetSpan(va, size)); }