aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Memory
diff options
context:
space:
mode:
Diffstat (limited to 'ChocolArm64/Memory')
-rw-r--r--ChocolArm64/Memory/AMemory.cs4
-rw-r--r--ChocolArm64/Memory/AMemoryAlloc.cs35
-rw-r--r--ChocolArm64/Memory/AMemoryMapInfo.cs2
-rw-r--r--ChocolArm64/Memory/AMemoryMgr.cs198
4 files changed, 73 insertions, 166 deletions
diff --git a/ChocolArm64/Memory/AMemory.cs b/ChocolArm64/Memory/AMemory.cs
index f2abffbf..0d202fed 100644
--- a/ChocolArm64/Memory/AMemory.cs
+++ b/ChocolArm64/Memory/AMemory.cs
@@ -41,9 +41,9 @@ namespace ChocolArm64.Memory
private byte* RamPtr;
- public AMemory(IntPtr Ram, AMemoryAlloc Allocator)
+ public AMemory(IntPtr Ram)
{
- Manager = new AMemoryMgr(Allocator);
+ Manager = new AMemoryMgr();
Monitors = new Dictionary<int, ExMonitor>();
diff --git a/ChocolArm64/Memory/AMemoryAlloc.cs b/ChocolArm64/Memory/AMemoryAlloc.cs
deleted file mode 100644
index b11e7793..00000000
--- a/ChocolArm64/Memory/AMemoryAlloc.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using ChocolArm64.Exceptions;
-
-namespace ChocolArm64.Memory
-{
- public class AMemoryAlloc
- {
- private long PhysPos;
-
- public long Alloc(long Size)
- {
- long Position = PhysPos;
-
- Size = AMemoryHelper.PageRoundUp(Size);
-
- PhysPos += Size;
-
- if (PhysPos > AMemoryMgr.RamSize || PhysPos < 0)
- {
- throw new VmmOutOfMemoryException(Size);
- }
-
- return Position;
- }
-
- public void Free(long Position)
- {
- //TODO
- }
-
- public long GetFreeMem()
- {
- return AMemoryMgr.RamSize - PhysPos;
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/AMemoryMapInfo.cs b/ChocolArm64/Memory/AMemoryMapInfo.cs
index 44b2cc07..02dd3055 100644
--- a/ChocolArm64/Memory/AMemoryMapInfo.cs
+++ b/ChocolArm64/Memory/AMemoryMapInfo.cs
@@ -1,6 +1,6 @@
namespace ChocolArm64.Memory
{
- public struct AMemoryMapInfo
+ public class AMemoryMapInfo
{
public long Position { get; private set; }
public long Size { get; private set; }
diff --git a/ChocolArm64/Memory/AMemoryMgr.cs b/ChocolArm64/Memory/AMemoryMgr.cs
index c8869e03..bc364452 100644
--- a/ChocolArm64/Memory/AMemoryMgr.cs
+++ b/ChocolArm64/Memory/AMemoryMgr.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace ChocolArm64.Memory
{
public class AMemoryMgr
@@ -5,22 +7,20 @@ namespace ChocolArm64.Memory
public const long AddrSize = RamSize;
public const long RamSize = 4L * 1024 * 1024 * 1024;
- private const int PTLvl0Bits = 11;
- private const int PTLvl1Bits = 13;
- private const int PTPageBits = 12;
-
- private const int PTLvl0Size = 1 << PTLvl0Bits;
- private const int PTLvl1Size = 1 << PTLvl1Bits;
- public const int PageSize = 1 << PTPageBits;
+ private const int PTLvl0Bits = 10;
+ private const int PTLvl1Bits = 10;
+ private const int PTPageBits = 12;
- private const int PTLvl0Mask = PTLvl0Size - 1;
- private const int PTLvl1Mask = PTLvl1Size - 1;
- public const int PageMask = PageSize - 1;
+ private const int PTLvl0Size = 1 << PTLvl0Bits;
+ private const int PTLvl1Size = 1 << PTLvl1Bits;
+ public const int PageSize = 1 << PTPageBits;
- private const int PTLvl0Bit = PTPageBits + PTLvl0Bits;
- private const int PTLvl1Bit = PTPageBits;
+ private const int PTLvl0Mask = PTLvl0Size - 1;
+ private const int PTLvl1Mask = PTLvl1Size - 1;
+ public const int PageMask = PageSize - 1;
- private AMemoryAlloc Allocator;
+ private const int PTLvl0Bit = PTPageBits + PTLvl1Bits;
+ private const int PTLvl1Bit = PTPageBits;
private enum PTMap
{
@@ -47,132 +47,24 @@ namespace ChocolArm64.Memory
private PTEntry[][] PageTable;
- private bool IsHeapInitialized;
-
- public long HeapAddr { get; private set; }
- public long HeapSize { get; private set; }
-
- public AMemoryMgr(AMemoryAlloc Allocator)
+ public AMemoryMgr()
{
- this.Allocator = Allocator;
-
PageTable = new PTEntry[PTLvl0Size][];
}
- public long GetTotalMemorySize()
+ public void Map(long Position, long Size, int Type, AMemoryPerm Perm)
{
- return Allocator.GetFreeMem() + GetUsedMemorySize();
- }
-
- public long GetUsedMemorySize()
- {
- long Size = 0;
-
- for (int L0 = 0; L0 < PageTable.Length; L0++)
- {
- if (PageTable[L0] == null)
- {
- continue;
- }
-
- for (int L1 = 0; L1 < PageTable[L0].Length; L1++)
- {
- Size += PageTable[L0][L1].Map != PTMap.Unmapped ? PageSize : 0;
- }
- }
-
- return Size;
- }
-
- public bool SetHeapAddr(long Position)
- {
- if (!IsHeapInitialized)
- {
- HeapAddr = Position;
-
- IsHeapInitialized = true;
-
- return true;
- }
-
- return false;
+ SetPTEntry(Position, Size, new PTEntry(PTMap.Mapped, Perm, Type, 0));
}
- public void SetHeapSize(long Size, int Type)
+ public void Unmap(long Position, long Size)
{
- //TODO: Return error when theres no enough space to allocate heap.
- Size = AMemoryHelper.PageRoundUp(Size);
-
- long Position = HeapAddr;
-
- if ((ulong)Size < (ulong)HeapSize)
- {
- //Try to free now free area if size is smaller than old size.
- Position += Size;
-
- while ((ulong)Size < (ulong)HeapSize)
- {
- Allocator.Free(Position);
-
- Position += PageSize;
- }
- }
- else
- {
- //Allocate extra needed size.
- Position += HeapSize;
- Size -= HeapSize;
-
- MapPhys(Position, Size, Type, AMemoryPerm.RW);
- }
-
- HeapSize = Size;
+ SetPTEntry(Position, Size, new PTEntry(PTMap.Unmapped, 0, 0, 0));
}
- public void MapPhys(long Position, long Size, int Type, AMemoryPerm Perm)
+ public void Unmap(long Position, long Size, int Type)
{
- while (Size > 0)
- {
- if (!IsMapped(Position))
- {
- SetPTEntry(Position, new PTEntry(PTMap.Mapped, Perm, Type, 0));
- }
-
- long CPgSize = PageSize - (Position & PageMask);
-
- Position += CPgSize;
- Size -= CPgSize;
- }
- }
-
- public void MapMirror(long Src, long Dst, long Size, int Type)
- {
- Src = AMemoryHelper.PageRoundDown(Src);
- Dst = AMemoryHelper.PageRoundDown(Dst);
-
- Size = AMemoryHelper.PageRoundUp(Size);
-
- long PagesCount = Size / PageSize;
-
- while (PagesCount-- > 0)
- {
- PTEntry SrcEntry = GetPTEntry(Src);
- PTEntry DstEntry = GetPTEntry(Dst);
-
- DstEntry.Map = PTMap.Mapped;
- DstEntry.Type = Type;
- DstEntry.Perm = SrcEntry.Perm;
-
- SrcEntry.Perm = AMemoryPerm.None;
-
- SrcEntry.Attr |= 1;
-
- SetPTEntry(Src, SrcEntry);
- SetPTEntry(Dst, DstEntry);
-
- Src += PageSize;
- Dst += PageSize;
- }
+ SetPTEntry(Position, Size, Type, new PTEntry(PTMap.Unmapped, 0, 0, 0));
}
public void Reprotect(long Position, long Size, AMemoryPerm Perm)
@@ -197,12 +89,22 @@ namespace ChocolArm64.Memory
public AMemoryMapInfo GetMapInfo(long Position)
{
+ if (!IsValidPosition(Position))
+ {
+ return null;
+ }
+
Position = AMemoryHelper.PageRoundDown(Position);
PTEntry BaseEntry = GetPTEntry(Position);
bool IsSameSegment(long Pos)
{
+ if (!IsValidPosition(Pos))
+ {
+ return false;
+ }
+
PTEntry Entry = GetPTEntry(Pos);
return Entry.Map == BaseEntry.Map &&
@@ -269,6 +171,16 @@ namespace ChocolArm64.Memory
return GetPTEntry(Position).Perm.HasFlag(Perm);
}
+ public bool IsValidPosition(long Position)
+ {
+ if (Position >> PTLvl0Bits + PTLvl1Bits + PTPageBits != 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
public bool IsMapped(long Position)
{
if (Position >> PTLvl0Bits + PTLvl1Bits + PTPageBits != 0)
@@ -300,8 +212,38 @@ namespace ChocolArm64.Memory
return PageTable[L0][L1];
}
+ private void SetPTEntry(long Position, long Size, PTEntry Entry)
+ {
+ while (Size > 0)
+ {
+ SetPTEntry(Position, Entry);
+
+ Position += PageSize;
+ Size -= PageSize;
+ }
+ }
+
+ private void SetPTEntry(long Position, long Size, int Type, PTEntry Entry)
+ {
+ while (Size > 0)
+ {
+ if (GetPTEntry(Position).Type == Type)
+ {
+ SetPTEntry(Position, Entry);
+ }
+
+ Position += PageSize;
+ Size -= PageSize;
+ }
+ }
+
private void SetPTEntry(long Position, PTEntry Entry)
{
+ if (!IsValidPosition(Position))
+ {
+ throw new ArgumentOutOfRangeException(nameof(Position));
+ }
+
long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask;
long L1 = (Position >> PTLvl1Bit) & PTLvl1Mask;