aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs14
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs24
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Memory/KPageTableHostMapped.cs20
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs10
-rw-r--r--Ryujinx.Memory/MemoryBlock.cs9
5 files changed, 62 insertions, 15 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs
index 20a13f57..d7ee04e3 100644
--- a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs
@@ -86,7 +86,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
}
/// <inheritdoc/>
- protected override KernelResult MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission)
+ protected override KernelResult MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
{
ulong size = pagesCount * PageSize;
@@ -99,11 +99,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
Context.MemoryManager.IncrementPagesReferenceCount(srcPa, pagesCount);
}
+ if (shouldFillPages)
+ {
+ _cpuMemory.Fill(dstVa, size, fillValue);
+ }
+
return KernelResult.Success;
}
/// <inheritdoc/>
- protected override KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission)
+ protected override KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
{
using var scopedPageList = new KScopedPageList(Context.MemoryManager, pageList);
@@ -118,6 +123,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
_cpuMemory.Map(currentVa, Context.Memory.GetPointer(addr, size), size);
+ if (shouldFillPages)
+ {
+ _cpuMemory.Fill(currentVa, size, fillValue);
+ }
+
currentVa += size;
}
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
index 965e03d9..ff87ecb7 100644
--- a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
@@ -75,6 +75,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public abstract bool SupportsMemoryAliasing { get; }
+ private MemoryFillValue _heapFillValue;
+ private MemoryFillValue _ipcFillValue;
+
public KPageTableBase(KernelContext context)
{
Context = context;
@@ -82,6 +85,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
_blockManager = new KMemoryBlockManager();
_isKernel = false;
+
+ _heapFillValue = MemoryFillValue.Zero;
+ _ipcFillValue = MemoryFillValue.Zero;
}
private static readonly int[] AddrSpaceSizes = new int[] { 32, 36, 32, 39 };
@@ -299,6 +305,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
TlsIoRegionStart = tlsIoRegion.Start;
TlsIoRegionEnd = tlsIoRegion.End;
+ // TODO: Check kernel configuration via secure monitor call when implemented to set memory fill values.
+
_currentHeapAddr = HeapRegionStart;
_heapCapacity = 0;
PhysicalMemoryUsage = 0;
@@ -738,7 +746,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return KernelResult.InvalidMemState;
}
- result = MapPages(_currentHeapAddr, pageList, KMemoryPermission.ReadAndWrite);
+ result = MapPages(_currentHeapAddr, pageList, KMemoryPermission.ReadAndWrite, true, (byte)_heapFillValue);
if (result != KernelResult.Success)
{
@@ -1783,7 +1791,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
{
ulong unusedSizeBefore = address - addressTruncated;
- Context.Memory.ZeroFill(GetDramAddressFromPa(dstFirstPagePa), unusedSizeBefore);
+ Context.Memory.Fill(GetDramAddressFromPa(dstFirstPagePa), unusedSizeBefore, (byte)_ipcFillValue);
ulong copySize = addressRounded <= endAddr ? addressRounded - address : size;
var data = srcPageTable.GetSpan(addressTruncated + unusedSizeBefore, (int)copySize);
@@ -1801,7 +1809,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
if (unusedSizeAfter != 0)
{
- Context.Memory.ZeroFill(GetDramAddressFromPa(firstPageFillAddress), unusedSizeAfter);
+ Context.Memory.Fill(GetDramAddressFromPa(firstPageFillAddress), unusedSizeAfter, (byte)_ipcFillValue);
}
KernelResult result = MapPages(currentVa, 1, dstFirstPagePa, permission);
@@ -1853,7 +1861,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
unusedSizeAfter = PageSize;
}
- Context.Memory.ZeroFill(GetDramAddressFromPa(lastPageFillAddr), unusedSizeAfter);
+ Context.Memory.Fill(GetDramAddressFromPa(lastPageFillAddr), unusedSizeAfter, (byte)_ipcFillValue);
KernelResult result = MapPages(currentVa, 1, dstLastPagePa, permission);
@@ -2779,8 +2787,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
/// <param name="pagesCount">Number of pages to map</param>
/// <param name="srcPa">Physical address where the pages should be mapped. May be ignored if aliasing is not supported</param>
/// <param name="permission">Permission of the region to be mapped</param>
+ /// <param name="shouldFillPages">Indicate if the pages should be filled with the <paramref name="fillValue"/> value</param>
+ /// <param name="fillValue">The value used to fill pages when <paramref name="shouldFillPages"/> is set to true</param>
/// <returns>Result of the mapping operation</returns>
- protected abstract KernelResult MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission);
+ protected abstract KernelResult MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission, bool shouldFillPages = false, byte fillValue = 0);
/// <summary>
/// Maps a region of memory into the specified physical memory region.
@@ -2788,8 +2798,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
/// <param name="address">Destination virtual address that should be mapped</param>
/// <param name="pageList">List of physical memory pages where the pages should be mapped. May be ignored if aliasing is not supported</param>
/// <param name="permission">Permission of the region to be mapped</param>
+ /// <param name="shouldFillPages">Indicate if the pages should be filled with the <paramref name="fillValue"/> value</param>
+ /// <param name="fillValue">The value used to fill pages when <paramref name="shouldFillPages"/> is set to true</param>
/// <returns>Result of the mapping operation</returns>
- protected abstract KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission);
+ protected abstract KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission, bool shouldFillPages = false, byte fillValue = 0);
/// <summary>
/// Maps a region of memory into the specified host memory ranges.
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableHostMapped.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableHostMapped.cs
index cd51bab7..29a7b2ed 100644
--- a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableHostMapped.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableHostMapped.cs
@@ -70,16 +70,30 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
}
/// <inheritdoc/>
- protected override KernelResult MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission)
+ protected override KernelResult MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
{
_cpuMemory.Map(dstVa, 0, pagesCount * PageSize);
+
+ if (shouldFillPages)
+ {
+ _cpuMemory.Fill(dstVa, pagesCount * PageSize, fillValue);
+ }
+
return KernelResult.Success;
}
/// <inheritdoc/>
- protected override KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission)
+ protected override KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
{
- _cpuMemory.Map(address, 0, pageList.GetPagesCount() * PageSize);
+ ulong pagesCount = pageList.GetPagesCount();
+
+ _cpuMemory.Map(address, 0, pagesCount * PageSize);
+
+ if (shouldFillPages)
+ {
+ _cpuMemory.Fill(address, pagesCount * PageSize, fillValue);
+ }
+
return KernelResult.Success;
}
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs
new file mode 100644
index 00000000..cdc892fc
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Kernel.Memory
+{
+ enum MemoryFillValue : byte
+ {
+ Zero = 0,
+ Stack = 0x58,
+ Ipc = 0x59,
+ Heap = 0x5A,
+ }
+}
diff --git a/Ryujinx.Memory/MemoryBlock.cs b/Ryujinx.Memory/MemoryBlock.cs
index 25c66dfe..3561b81a 100644
--- a/Ryujinx.Memory/MemoryBlock.cs
+++ b/Ryujinx.Memory/MemoryBlock.cs
@@ -216,13 +216,14 @@ namespace Ryujinx.Memory
}
/// <summary>
- /// Fills a region of memory with zeros.
+ /// Fills a region of memory with <paramref name="value"/>.
/// </summary>
- /// <param name="offset">Offset of the region to fill with zeros</param>
+ /// <param name="offset">Offset of the region to fill with <paramref name="value"/></param>
/// <param name="size">Size in bytes of the region to fill</param>
+ /// <param name="value">Value to use for the fill</param>
/// <exception cref="ObjectDisposedException">Throw when the memory block has already been disposed</exception>
/// <exception cref="InvalidMemoryRegionException">Throw when either <paramref name="offset"/> or <paramref name="size"/> are out of range</exception>
- public void ZeroFill(ulong offset, ulong size)
+ public void Fill(ulong offset, ulong size, byte value)
{
const int MaxChunkSize = 1 << 24;
@@ -230,7 +231,7 @@ namespace Ryujinx.Memory
{
int copySize = (int)Math.Min(MaxChunkSize, size - subOffset);
- GetSpan(offset + subOffset, copySize).Fill(0);
+ GetSpan(offset + subOffset, copySize).Fill(value);
}
}