2023-01-17 04:13:24 +00:00
|
|
|
using Ryujinx.Memory;
|
|
|
|
using System;
|
|
|
|
|
|
|
|
namespace Ryujinx.Cpu
|
|
|
|
{
|
2023-06-20 16:33:54 +01:00
|
|
|
public class AddressSpace : IDisposable
|
2023-01-17 04:13:24 +00:00
|
|
|
{
|
|
|
|
private readonly MemoryBlock _backingMemory;
|
|
|
|
|
|
|
|
public MemoryBlock Base { get; }
|
|
|
|
public MemoryBlock Mirror { get; }
|
|
|
|
|
2023-06-20 16:33:54 +01:00
|
|
|
public ulong AddressSpaceSize { get; }
|
|
|
|
|
2024-04-06 17:51:44 +01:00
|
|
|
public AddressSpace(MemoryBlock backingMemory, MemoryBlock baseMemory, MemoryBlock mirrorMemory, ulong addressSpaceSize)
|
2023-01-17 04:13:24 +00:00
|
|
|
{
|
|
|
|
_backingMemory = backingMemory;
|
|
|
|
|
2023-06-20 16:33:54 +01:00
|
|
|
Base = baseMemory;
|
|
|
|
Mirror = mirrorMemory;
|
|
|
|
AddressSpaceSize = addressSpaceSize;
|
|
|
|
}
|
|
|
|
|
2024-04-06 17:51:44 +01:00
|
|
|
public static bool TryCreate(MemoryBlock backingMemory, ulong asSize, out AddressSpace addressSpace)
|
2023-06-20 16:33:54 +01:00
|
|
|
{
|
|
|
|
addressSpace = null;
|
|
|
|
|
2023-07-24 17:35:04 +01:00
|
|
|
const MemoryAllocationFlags AsFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
|
2023-01-17 04:13:24 +00:00
|
|
|
|
2023-06-20 16:33:54 +01:00
|
|
|
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
|
|
|
|
|
|
|
|
// Attempt to create the address space with expected size or try to reduce it until it succeed.
|
|
|
|
for (ulong addressSpaceSize = asSize; addressSpaceSize >= minAddressSpaceSize; addressSpaceSize >>= 1)
|
|
|
|
{
|
|
|
|
MemoryBlock baseMemory = null;
|
|
|
|
MemoryBlock mirrorMemory = null;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2023-07-24 17:35:04 +01:00
|
|
|
baseMemory = new MemoryBlock(addressSpaceSize, AsFlags);
|
|
|
|
mirrorMemory = new MemoryBlock(addressSpaceSize, AsFlags);
|
2024-04-06 17:51:44 +01:00
|
|
|
addressSpace = new AddressSpace(backingMemory, baseMemory, mirrorMemory, addressSpaceSize);
|
2023-06-20 16:33:54 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2023-06-26 02:37:12 +01:00
|
|
|
catch (SystemException)
|
2023-06-20 16:33:54 +01:00
|
|
|
{
|
|
|
|
baseMemory?.Dispose();
|
|
|
|
mirrorMemory?.Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return addressSpace != null;
|
2023-01-17 04:13:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
|
|
|
|
{
|
2024-04-06 17:51:44 +01:00
|
|
|
Base.MapView(_backingMemory, pa, va, size);
|
|
|
|
Mirror.MapView(_backingMemory, pa, va, size);
|
2023-01-17 04:13:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Unmap(ulong va, ulong size)
|
|
|
|
{
|
2024-04-06 17:51:44 +01:00
|
|
|
Base.UnmapView(_backingMemory, va, size);
|
|
|
|
Mirror.UnmapView(_backingMemory, va, size);
|
2023-01-17 04:13:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
{
|
2023-07-01 03:18:52 +01:00
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
|
2023-01-17 04:13:24 +00:00
|
|
|
Base.Dispose();
|
|
|
|
Mirror.Dispose();
|
|
|
|
}
|
|
|
|
}
|
2023-07-01 03:18:52 +01:00
|
|
|
}
|