Enable full memory checking on all memory accesses

This commit is contained in:
gdkchan 2018-03-08 16:27:16 -03:00
parent be0e4007dc
commit b8fd849247
20 changed files with 499 additions and 380 deletions

View file

@ -41,9 +41,9 @@ namespace ChocolArm64.Memory
private byte* RamPtr;
public AMemory(IntPtr Ram)
public AMemory(IntPtr Ram, long RamSize, int AddressSpaceBits)
{
Manager = new AMemoryMgr();
Manager = new AMemoryMgr(RamSize, AddressSpaceBits);
Monitors = new Dictionary<int, ExMonitor>();
@ -142,90 +142,121 @@ namespace ChocolArm64.Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public byte ReadByte(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
byte* Ptr = RamPtr + Position;
return *((byte*)(RamPtr + (uint)Position));
if (Manager.IsDirectRead(Position))
{
return *Ptr;
}
return ReadByteSlow(Position);
}
private byte ReadByteSlow(long Position)
{
EnsureAccessIsValid(Position, AMemoryPerm.Read);
long PA = Manager.TranslatePosition(Position);
return *(RamPtr + PA);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ushort ReadUInt16(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
ushort* Ptr = (ushort*)(RamPtr + Position);
return *((ushort*)(RamPtr + (uint)Position));
if (Manager.IsDirectRead(Position))
{
return *Ptr;
}
throw new VmmPageFaultException(Position);
}
private ushort ReadUInt16Slow(long Position)
{
EnsureAccessIsValid(Position, AMemoryPerm.Read);
EnsureAccessIsValid(Position + 1, AMemoryPerm.Read);
long PA = Manager.TranslatePosition(Position);
return *((ushort*)(RamPtr + PA));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint ReadUInt32(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
uint* Ptr = (uint*)(RamPtr + Position);
return *((uint*)(RamPtr + (uint)Position));
if (Manager.IsDirectRead(Position))
{
return *Ptr;
}
return ReadUInt32Slow(Position);
}
private uint ReadUInt32Slow(long Position)
{
EnsureAccessIsValid(Position, AMemoryPerm.Read);
EnsureAccessIsValid(Position + 3, AMemoryPerm.Read);
long PA = Manager.TranslatePosition(Position);
return *((uint*)(RamPtr + PA));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong ReadUInt64(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
ulong* Ptr = (ulong*)(RamPtr + Position);
return *((ulong*)(RamPtr + (uint)Position));
if (Manager.IsDirectRead(Position))
{
return *Ptr;
}
return ReadUInt64Slow(Position);
}
private ulong ReadUInt64Slow(long Position)
{
EnsureAccessIsValid(Position, AMemoryPerm.Read);
EnsureAccessIsValid(Position + 7, AMemoryPerm.Read);
long PA = Manager.TranslatePosition(Position);
return *((ulong*)(RamPtr + PA));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AVec ReadVector8(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
return new AVec() { B0 = ReadByte(Position) };
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AVec ReadVector16(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
return new AVec() { H0 = ReadUInt16(Position) };
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AVec ReadVector32(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
return new AVec() { W0 = ReadUInt32(Position) };
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AVec ReadVector64(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
return new AVec() { X0 = ReadUInt64(Position) };
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AVec ReadVector128(long Position)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Read);
#endif
return new AVec()
{
X0 = ReadUInt64(Position + 0),
@ -241,94 +272,161 @@ namespace ChocolArm64.Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteByte(long Position, byte Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
byte* Ptr = RamPtr + Position;
*((byte*)(RamPtr + (uint)Position)) = Value;
if (Manager.IsDirectWrite(Position))
{
*Ptr = Value;
return;
}
WriteByteSlow(Position, Value);
}
private void WriteByteSlow(long Position, byte Value)
{
EnsureAccessIsValid(Position, AMemoryPerm.Write);
long PA = Manager.TranslatePosition(Position);
*(RamPtr + PA) = Value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteUInt16(long Position, ushort Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
ushort* Ptr = (ushort*)(RamPtr + Position);
*((ushort*)(RamPtr + (uint)Position)) = Value;
if (Manager.IsDirectWrite(Position))
{
*Ptr = Value;
return;
}
WriteUInt16Slow(Position, Value);
}
private void WriteUInt16Slow(long Position, ushort Value)
{
EnsureAccessIsValid(Position, AMemoryPerm.Write);
EnsureAccessIsValid(Position + 1, AMemoryPerm.Write);
long PA = Manager.TranslatePosition(Position);
*((ushort*)(RamPtr + PA)) = Value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteUInt32(long Position, uint Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
uint* Ptr = (uint*)(RamPtr + Position);
*((uint*)(RamPtr + (uint)Position)) = Value;
if (Manager.IsDirectWrite(Position))
{
*Ptr = Value;
return;
}
WriteUInt32Slow(Position, Value);
}
private void WriteUInt32Slow(long Position, uint Value)
{
EnsureAccessIsValid(Position, AMemoryPerm.Write);
EnsureAccessIsValid(Position + 3, AMemoryPerm.Write);
long PA = Manager.TranslatePosition(Position);
*((uint*)(RamPtr + PA)) = Value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteUInt64(long Position, ulong Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
ulong* Ptr = (ulong*)(RamPtr + Position);
*((ulong*)(RamPtr + (uint)Position)) = Value;
if (Manager.IsDirectWrite(Position))
{
*Ptr = Value;
return;
}
WriteUInt64Slow(Position, Value);
}
private void WriteUInt64Slow(long Position, ulong Value)
{
EnsureAccessIsValid(Position, AMemoryPerm.Write);
EnsureAccessIsValid(Position + 7, AMemoryPerm.Write);
long PA = Manager.TranslatePosition(Position);
*((ulong*)(RamPtr + PA)) = Value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteVector8(long Position, AVec Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
WriteByte(Position, Value.B0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteVector16(long Position, AVec Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
WriteUInt16(Position, Value.H0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteVector32(long Position, AVec Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
WriteUInt32(Position, Value.W0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteVector64(long Position, AVec Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
WriteUInt64(Position, Value.X0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteVector128(long Position, AVec Value)
{
#if DEBUG
EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif
WriteUInt64(Position + 0, Value.X0);
WriteUInt64(Position + 8, Value.X1);
}
public void WriteDirectUnchecked(long Position, byte[] Data)
{
byte* Ptr = (byte*)(RamPtr + Position);
int Pages = (Data.Length + AMemoryMgr.PageMask) / AMemoryMgr.PageSize;
int RemSize = Data.Length;
for (int Page = 0; Page < Pages; Page++)
{
int Offset = Page * AMemoryMgr.PageSize;
if (!Manager.IsMapped(Position + Offset))
{
throw new VmmPageFaultException(Position + Offset);
}
int ToCopy = Math.Min(AMemoryMgr.PageSize, RemSize);
for (; Offset < Page * AMemoryMgr.PageSize + ToCopy; Offset++)
{
*Ptr++ = Data[Offset];
}
RemSize -= AMemoryMgr.PageSize;
}
}
private void EnsureAccessIsValid(long Position, AMemoryPerm Perm)
{
if (!Manager.IsMapped(Position))

View file

@ -4,28 +4,41 @@ namespace ChocolArm64.Memory
{
public class AMemoryMgr
{
public const long AddrSize = RamSize;
public const long RamSize = 4L * 1024 * 1024 * 1024;
private ulong RamSize;
private ulong AddressSpaceSize;
private int PTLvl0Bits;
private int PTLvl1Bits;
private int PTLvl0Size;
private int PTLvl1Size;
private int PTLvl0Mask;
private int PTLvl1Mask;
private int PTLvl0Bit;
private const int PTLvl0Bits = 10;
private const int PTLvl1Bits = 10;
private const int PTPageBits = 12;
private const int PTLvl0Size = 1 << PTLvl0Bits;
private const int PTLvl1Size = 1 << PTLvl1Bits;
public const int PageSize = 1 << PTPageBits;
public const int PageSize = 1 << PTPageBits;
private const int PTLvl0Mask = PTLvl0Size - 1;
private const int PTLvl1Mask = PTLvl1Size - 1;
public const int PageMask = PageSize - 1;
public const int PageMask = PageSize - 1;
private const int PTLvl0Bit = PTPageBits + PTLvl1Bits;
private const int PTLvl1Bit = PTPageBits;
private const int PTLvl1Bit = PTPageBits;
private enum PTMap
private enum PTMap : byte
{
Unmapped,
Mapped
Unmapped = 0,
Mapped = 1,
Direct = 1 << 5,
DirectRead = Direct | 1 << 6,
DirectWrite = Direct | 1 << 7,
DirectRW =
DirectRead |
DirectWrite
}
private struct PTEntry
@ -33,38 +46,121 @@ namespace ChocolArm64.Memory
public PTMap Map;
public AMemoryPerm Perm;
public long Position;
public int Type;
public int Attr;
public PTEntry(PTMap Map, AMemoryPerm Perm, int Type, int Attr)
public PTEntry(PTMap Map, long Position, AMemoryPerm Perm, int Type, int Attr)
{
this.Map = Map;
this.Position = Position;
this.Perm = Perm;
this.Type = Type;
this.Attr = Attr;
}
}
private PTMap[] MapTypes;
private PTEntry[][] PageTable;
public AMemoryMgr()
public AMemoryMgr(long RamSize, int AddressSpaceBits)
{
this.RamSize = (ulong)RamSize;
AddressSpaceSize = 1UL << AddressSpaceBits;
int RemBits = AddressSpaceBits - PTPageBits;
PTLvl0Bits = RemBits >> 1;
PTLvl1Bits = RemBits - PTLvl0Bits;
PTLvl0Size = 1 << PTLvl0Bits;
PTLvl1Size = 1 << PTLvl1Bits;
PTLvl0Mask = PTLvl0Size - 1;
PTLvl1Mask = PTLvl1Size - 1;
PTLvl0Bit = PTPageBits + PTLvl1Bits;
MapTypes = new PTMap[1 << RemBits];
PageTable = new PTEntry[PTLvl0Size][];
}
public void Map(long Position, long Size, int Type, AMemoryPerm Perm)
public void MapDirectRX(long Position, long Size, int Type)
{
SetPTEntry(Position, Size, new PTEntry(PTMap.Mapped, Perm, Type, 0));
if ((ulong)Position >= RamSize)
{
throw new ArgumentOutOfRangeException(nameof(Position));
}
if ((ulong)(Position + Size) > RamSize)
{
throw new ArgumentOutOfRangeException(nameof(Size));
}
SetPTEntry(Position, Size, new PTEntry(PTMap.DirectRead, 0, AMemoryPerm.RX, Type, 0));
}
public void MapDirectRO(long Position, long Size, int Type)
{
if ((ulong)Position >= RamSize)
{
throw new ArgumentOutOfRangeException(nameof(Position));
}
if ((ulong)(Position + Size) > RamSize)
{
throw new ArgumentOutOfRangeException(nameof(Size));
}
SetPTEntry(Position, Size, new PTEntry(PTMap.DirectRead, 0, AMemoryPerm.Read, Type, 0));
}
public void MapDirectRW(long Position, long Size, int Type)
{
if ((ulong)Position >= RamSize)
{
throw new ArgumentOutOfRangeException(nameof(Position));
}
if ((ulong)(Position + Size) > RamSize)
{
throw new ArgumentOutOfRangeException(nameof(Size));
}
SetPTEntry(Position, Size, new PTEntry(PTMap.DirectRW, 0, AMemoryPerm.RW, Type, 0));
}
public void Map(long VA, long PA, long Size, int Type, AMemoryPerm Perm)
{
if ((ulong)VA >= AddressSpaceSize)
{
throw new ArgumentOutOfRangeException(nameof(VA));
}
if ((ulong)PA >= RamSize)
{
throw new ArgumentOutOfRangeException(nameof(PA));
}
if ((ulong)(PA + Size) > RamSize || (ulong)(VA + Size) > AddressSpaceSize)
{
throw new ArgumentOutOfRangeException(nameof(Size));
}
SetPTEntry(VA, Size, new PTEntry(PTMap.Mapped, PA, Perm, Type, 0));
}
public void Unmap(long Position, long Size)
{
SetPTEntry(Position, Size, new PTEntry(PTMap.Unmapped, 0, 0, 0));
SetPTEntry(Position, Size, new PTEntry(PTMap.Unmapped, 0, 0, 0, 0));
}
public void Unmap(long Position, long Size, int Type)
{
SetPTEntry(Position, Size, Type, new PTEntry(PTMap.Unmapped, 0, 0, 0));
SetPTEntry(Position, Size, Type, new PTEntry(PTMap.Unmapped, 0, 0, 0, 0));
}
public void Reprotect(long Position, long Size, AMemoryPerm Perm)
@ -121,7 +217,7 @@ namespace ChocolArm64.Memory
Start -= PageSize;
}
while (End < AddrSize && IsSameSegment(End))
while ((ulong)End < AddressSpaceSize && IsSameSegment(End))
{
End += PageSize;
}
@ -199,6 +295,35 @@ namespace ChocolArm64.Memory
return PageTable[L0][L1].Map != PTMap.Unmapped;
}
public long TranslatePosition(long Position)
{
if (IsDirect(Position))
{
return Position;
}
else
{
long BasePosition = GetPTEntry(Position).Position;
return BasePosition + (Position & AMemoryMgr.PageMask);
}
}
public bool IsDirect(long Position)
{
return (MapTypes[(ulong)Position >> PTPageBits] & PTMap.Direct) != 0;
}
public bool IsDirectRead(long Position)
{
return (MapTypes[(ulong)Position >> PTPageBits] & PTMap.DirectRead) != 0;
}
public bool IsDirectWrite(long Position)
{
return (MapTypes[(ulong)Position >> PTPageBits] & PTMap.DirectWrite) != 0;
}
private PTEntry GetPTEntry(long Position)
{
long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask;
@ -214,10 +339,14 @@ namespace ChocolArm64.Memory
private void SetPTEntry(long Position, long Size, PTEntry Entry)
{
Entry.Position &= ~PageMask;
while (Size > 0)
{
SetPTEntry(Position, Entry);
Entry.Position += PageSize;
Position += PageSize;
Size -= PageSize;
}
@ -225,12 +354,13 @@ namespace ChocolArm64.Memory
private void SetPTEntry(long Position, long Size, int Type, PTEntry Entry)
{
while (Size > 0)
Entry.Position &= ~PageMask;
while (Size > 0 && GetPTEntry(Position).Type == Type)
{
if (GetPTEntry(Position).Type == Type)
{
SetPTEntry(Position, Entry);
}
SetPTEntry(Position, Entry);
Entry.Position += PageSize;
Position += PageSize;
Size -= PageSize;
@ -253,6 +383,8 @@ namespace ChocolArm64.Memory
}
PageTable[L0][L1] = Entry;
MapTypes[Position >> PTPageBits] = Entry.Map;
}
}
}

View file

@ -3,7 +3,7 @@ using System;
namespace ChocolArm64.Memory
{
[Flags]
public enum AMemoryPerm
public enum AMemoryPerm : byte
{
None = 0,
Read = 1 << 0,

View file

@ -1,6 +1,4 @@
using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using System;
using System;
using System.Diagnostics;
namespace Ryujinx.Core.Input
@ -62,51 +60,16 @@ namespace Ryujinx.Core.Input
private const int HidEntryCount = 17;
private object ShMemLock;
private long[] ShMemPositions;
private IntPtr Ram;
public Hid(IntPtr Ram)
public long PA { get; private set; }
public Hid(IntPtr Ram, long PA)
{
this.Ram = Ram;
this.PA = PA;
ShMemLock = new object();
ShMemPositions = new long[0];
}
internal void ShMemMap(object sender, EventArgs e)
{
HSharedMem SharedMem = (HSharedMem)sender;
lock (ShMemLock)
{
ShMemPositions = SharedMem.GetVirtualPositions();
long BasePosition = ShMemPositions[ShMemPositions.Length - 1];
Logging.Info($"HID shared memory successfully mapped to 0x{BasePosition:x16}!");
Init(BasePosition);
}
}
internal void ShMemUnmap(object sender, EventArgs e)
{
HSharedMem SharedMem = (HSharedMem)sender;
lock (ShMemLock)
{
ShMemPositions = SharedMem.GetVirtualPositions();
}
}
private void Init(long BasePosition)
{
InitializeJoyconPair(
BasePosition,
JoyConColor.Body_Neon_Red,
JoyConColor.Buttons_Neon_Red,
JoyConColor.Body_Neon_Blue,
@ -114,13 +77,12 @@ namespace Ryujinx.Core.Input
}
private void InitializeJoyconPair(
long BasePosition,
JoyConColor LeftColorBody,
JoyConColor LeftColorButtons,
JoyConColor RightColorBody,
JoyConColor RightColorButtons)
{
long BaseControllerOffset = BasePosition + HidControllersOffset + 8 * HidControllerSize;
long BaseControllerOffset = HidControllersOffset + 8 * HidControllerSize;
HidControllerType Type =
HidControllerType.ControllerType_Handheld |
@ -159,123 +121,105 @@ namespace Ryujinx.Core.Input
HidJoystickPosition LeftStick,
HidJoystickPosition RightStick)
{
lock (ShMemLock)
{
foreach (long Position in ShMemPositions)
{
long ControllerOffset = Position + HidControllersOffset;
long ControllerOffset = HidControllersOffset;
ControllerOffset += (int)ControllerId * HidControllerSize;
ControllerOffset += (int)ControllerId * HidControllerSize;
ControllerOffset += HidControllerHeaderSize;
ControllerOffset += HidControllerHeaderSize;
ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize;
ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize;
long LastEntry = ReadInt64(ControllerOffset + 0x10);
long LastEntry = ReadInt64(ControllerOffset + 0x10);
long CurrEntry = (LastEntry + 1) % HidEntryCount;
long CurrEntry = (LastEntry + 1) % HidEntryCount;
long Timestamp = Stopwatch.GetTimestamp();
long Timestamp = Stopwatch.GetTimestamp();
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, HidEntryCount);
WriteInt64(ControllerOffset + 0x10, CurrEntry);
WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1);
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, HidEntryCount);
WriteInt64(ControllerOffset + 0x10, CurrEntry);
WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1);
ControllerOffset += HidControllersLayoutHeaderSize;
ControllerOffset += HidControllersLayoutHeaderSize;
ControllerOffset += CurrEntry * HidControllersInputEntrySize;
ControllerOffset += CurrEntry * HidControllersInputEntrySize;
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, Timestamp);
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, Timestamp);
WriteInt64(ControllerOffset + 0x10, (uint)Buttons);
WriteInt64(ControllerOffset + 0x10, (uint)Buttons);
WriteInt32(ControllerOffset + 0x18, LeftStick.DX);
WriteInt32(ControllerOffset + 0x1c, LeftStick.DY);
WriteInt32(ControllerOffset + 0x18, LeftStick.DX);
WriteInt32(ControllerOffset + 0x1c, LeftStick.DY);
WriteInt64(ControllerOffset + 0x20, RightStick.DX);
WriteInt64(ControllerOffset + 0x24, RightStick.DY);
WriteInt64(ControllerOffset + 0x20, RightStick.DX);
WriteInt64(ControllerOffset + 0x24, RightStick.DY);
WriteInt64(ControllerOffset + 0x28,
(uint)HidControllerConnState.Controller_State_Connected |
(uint)HidControllerConnState.Controller_State_Wired);
}
}
WriteInt64(ControllerOffset + 0x28,
(uint)HidControllerConnState.Controller_State_Connected |
(uint)HidControllerConnState.Controller_State_Wired);
}
public void SetTouchPoints(params HidTouchPoint[] Points)
{
lock (ShMemLock)
long TouchScreenOffset = HidTouchScreenOffset;
long LastEntry = ReadInt64(TouchScreenOffset + 0x10);
long CurrEntry = (LastEntry + 1) % HidEntryCount;
long Timestamp = ReadInt64(TouchScreenOffset) + 1;
WriteInt64(TouchScreenOffset + 0x0, Timestamp);
WriteInt64(TouchScreenOffset + 0x8, HidEntryCount);
WriteInt64(TouchScreenOffset + 0x10, CurrEntry);
WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1);
WriteInt64(TouchScreenOffset + 0x20, Timestamp);
long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize;
long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize;
TouchEntryOffset += CurrEntry * HidTouchEntrySize;
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
WriteInt64(TouchEntryOffset + 0x8, Points.Length);
TouchEntryOffset += HidTouchEntryHeaderSize;
const int Padding = 0;
int Index = 0;
foreach (HidTouchPoint Point in Points)
{
foreach (long Position in ShMemPositions)
{
long TouchScreenOffset = Position + HidTouchScreenOffset;
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
WriteInt32(TouchEntryOffset + 0x8, Padding);
WriteInt32(TouchEntryOffset + 0xc, Index++);
WriteInt32(TouchEntryOffset + 0x10, Point.X);
WriteInt32(TouchEntryOffset + 0x14, Point.Y);
WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX);
WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY);
WriteInt32(TouchEntryOffset + 0x20, Point.Angle);
WriteInt32(TouchEntryOffset + 0x24, Padding);
long LastEntry = ReadInt64(TouchScreenOffset + 0x10);
long CurrEntry = (LastEntry + 1) % HidEntryCount;
long Timestamp = ReadInt64(TouchScreenOffset) + 1;
WriteInt64(TouchScreenOffset + 0x0, Timestamp);
WriteInt64(TouchScreenOffset + 0x8, HidEntryCount);
WriteInt64(TouchScreenOffset + 0x10, CurrEntry);
WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1);
WriteInt64(TouchScreenOffset + 0x20, Timestamp);
long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize;
long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize;
TouchEntryOffset += CurrEntry * HidTouchEntrySize;
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
WriteInt64(TouchEntryOffset + 0x8, Points.Length);
TouchEntryOffset += HidTouchEntryHeaderSize;
const int Padding = 0;
int Index = 0;
foreach (HidTouchPoint Point in Points)
{
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
WriteInt32(TouchEntryOffset + 0x8, Padding);
WriteInt32(TouchEntryOffset + 0xc, Index++);
WriteInt32(TouchEntryOffset + 0x10, Point.X);
WriteInt32(TouchEntryOffset + 0x14, Point.Y);
WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX);
WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY);
WriteInt32(TouchEntryOffset + 0x20, Point.Angle);
WriteInt32(TouchEntryOffset + 0x24, Padding);
TouchEntryOffset += HidTouchEntryTouchSize;
}
}
TouchEntryOffset += HidTouchEntryTouchSize;
}
}
private unsafe long ReadInt64(long Position)
{
if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return 0;
return *((long*)((byte*)Ram + Position));
return *((long*)((byte*)Ram + PA + Position));
}
private unsafe void WriteInt32(long Position, int Value)
{
if ((ulong)Position + 4 > AMemoryMgr.AddrSize) return;
*((int*)((byte*)Ram + Position)) = Value;
*((int*)((byte*)Ram + PA + Position)) = Value;
}
private unsafe void WriteInt64(long Position, long Value)
{
if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return;
*((long*)((byte*)Ram + Position)) = Value;
*((long*)((byte*)Ram + PA + Position)) = Value;
}
}
}

View file

@ -28,13 +28,17 @@ namespace Ryujinx.Core.Loaders
this.ImageBase = ImageBase;
this.ImageEnd = ImageBase;
WriteData(ImageBase + Exe.TextOffset, Exe.Text, MemoryType.CodeStatic, AMemoryPerm.RX);
WriteData(ImageBase + Exe.ROOffset, Exe.RO, MemoryType.Normal, AMemoryPerm.Read);
WriteData(ImageBase + Exe.DataOffset, Exe.Data, MemoryType.Normal, AMemoryPerm.RW);
Memory.Manager.MapDirectRX(ImageBase + Exe.TextOffset, Exe.Text.Length, (int)MemoryType.CodeStatic);
Memory.Manager.MapDirectRO(ImageBase + Exe.ROOffset, Exe.RO.Length, (int)MemoryType.Normal);
Memory.Manager.MapDirectRW(ImageBase + Exe.DataOffset, Exe.Data.Length, (int)MemoryType.Normal);
Memory.WriteDirectUnchecked(ImageBase + Exe.TextOffset, Exe.Text);
Memory.WriteDirectUnchecked(ImageBase + Exe.ROOffset, Exe.RO);
Memory.WriteDirectUnchecked(ImageBase + Exe.DataOffset, Exe.Data);
if (Exe.Mod0Offset == 0)
{
int BssOffset = Exe.DataOffset + Exe.Data.Count;
int BssOffset = Exe.DataOffset + Exe.Data.Length;
int BssSize = Exe.BssSize;
MapBss(ImageBase + BssOffset, BssSize);
@ -90,25 +94,9 @@ namespace Ryujinx.Core.Loaders
}
}
private void WriteData(
long Position,
IList<byte> Data,
MemoryType Type,
AMemoryPerm Perm)
{
Memory.Manager.Map(Position, Data.Count, (int)Type, AMemoryPerm.Write);
for (int Index = 0; Index < Data.Count; Index++)
{
Memory.WriteByte(Position + Index, Data[Index]);
}
Memory.Manager.Reprotect(Position, Data.Count, Perm);
}
private void MapBss(long Position, long Size)
{
Memory.Manager.Map(Position, Size, (int)MemoryType.Normal, AMemoryPerm.RW);
Memory.Manager.MapDirectRW(Position, Size, (int)MemoryType.Normal);
}
private ElfRel GetRelocation(long Position)

View file

@ -1,12 +1,10 @@
using System.Collections.ObjectModel;
namespace Ryujinx.Core.Loaders.Executables
{
public interface IExecutable
{
ReadOnlyCollection<byte> Text { get; }
ReadOnlyCollection<byte> RO { get; }
ReadOnlyCollection<byte> Data { get; }
byte[] Text { get; }
byte[] RO { get; }
byte[] Data { get; }
int Mod0Offset { get; }
int TextOffset { get; }

View file

@ -1,18 +1,12 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
namespace Ryujinx.Core.Loaders.Executables
{
class Nro : IExecutable
{
private byte[] m_Text;
private byte[] m_RO;
private byte[] m_Data;
public ReadOnlyCollection<byte> Text => Array.AsReadOnly(m_Text);
public ReadOnlyCollection<byte> RO => Array.AsReadOnly(m_RO);
public ReadOnlyCollection<byte> Data => Array.AsReadOnly(m_Data);
public byte[] Text { get; private set; }
public byte[] RO { get; private set; }
public byte[] Data { get; private set; }
public int Mod0Offset { get; private set; }
public int TextOffset { get; private set; }
@ -54,9 +48,9 @@ namespace Ryujinx.Core.Loaders.Executables
return Reader.ReadBytes(Size);
}
m_Text = Read(TextOffset, TextSize);
m_RO = Read(ROOffset, ROSize);
m_Data = Read(DataOffset, DataSize);
Text = Read(TextOffset, TextSize);
RO = Read(ROOffset, ROSize);
Data = Read(DataOffset, DataSize);
}
}
}

View file

@ -1,19 +1,14 @@
using Ryujinx.Core.Loaders.Compression;
using System;
using System.Collections.ObjectModel;
using System.IO;
namespace Ryujinx.Core.Loaders.Executables
{
class Nso : IExecutable
{
private byte[] m_Text;
private byte[] m_RO;
private byte[] m_Data;
public ReadOnlyCollection<byte> Text => Array.AsReadOnly(m_Text);
public ReadOnlyCollection<byte> RO => Array.AsReadOnly(m_RO);
public ReadOnlyCollection<byte> Data => Array.AsReadOnly(m_Data);
public byte[] Text { get; private set; }
public byte[] RO { get; private set; }
public byte[] Data { get; private set; }
public int Mod0Offset { get; private set; }
public int TextOffset { get; private set; }
@ -82,38 +77,38 @@ namespace Ryujinx.Core.Loaders.Executables
//Text segment
Input.Seek(TextOffset, SeekOrigin.Begin);
m_Text = Reader.ReadBytes(TextSize);
Text = Reader.ReadBytes(TextSize);
if (Flags.HasFlag(NsoFlags.IsTextCompressed) || true)
{
m_Text = Lz4.Decompress(m_Text, TextDecSize);
Text = Lz4.Decompress(Text, TextDecSize);
}
//Read-only data segment
Input.Seek(ROOffset, SeekOrigin.Begin);
m_RO = Reader.ReadBytes(ROSize);
RO = Reader.ReadBytes(ROSize);
if (Flags.HasFlag(NsoFlags.IsROCompressed) || true)
{
m_RO = Lz4.Decompress(m_RO, RODecSize);
RO = Lz4.Decompress(RO, RODecSize);
}
//Data segment
Input.Seek(DataOffset, SeekOrigin.Begin);
m_Data = Reader.ReadBytes(DataSize);
Data = Reader.ReadBytes(DataSize);
if (Flags.HasFlag(NsoFlags.IsDataCompressed) || true)
{
m_Data = Lz4.Decompress(m_Data, DataDecSize);
Data = Lz4.Decompress(Data, DataDecSize);
}
using (MemoryStream Text = new MemoryStream(m_Text))
using (MemoryStream TextSegm = new MemoryStream(Text))
{
BinaryReader TextReader = new BinaryReader(Text);
BinaryReader TextReader = new BinaryReader(TextSegm);
Text.Seek(4, SeekOrigin.Begin);
TextSegm.Seek(4, SeekOrigin.Begin);
Mod0Offset = TextReader.ReadInt32();
}

View file

@ -1,43 +1,12 @@
using System;
using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.Handles
{
class HSharedMem
{
private List<long> Positions;
public long PA { get; private set; }
public EventHandler<EventArgs> MemoryMapped;
public EventHandler<EventArgs> MemoryUnmapped;
public HSharedMem()
public HSharedMem(long PA)
{
Positions = new List<long>();
}
public void AddVirtualPosition(long Position)
{
lock (Positions)
{
Positions.Add(Position);
MemoryMapped?.Invoke(this, EventArgs.Empty);
}
}
public void RemoveVirtualPosition(long Position)
{
lock (Positions)
{
Positions.Remove(Position);
MemoryUnmapped?.Invoke(this, EventArgs.Empty);
}
}
public long[] GetVirtualPositions()
{
return Positions.ToArray();
this.PA = PA;
}
}
}

View file

@ -7,7 +7,7 @@ namespace Ryujinx.Core.OsHle
//http://switchbrew.org/index.php?title=Homebrew_ABI
public static void WriteHbAbiData(AMemory Memory, long Position, int MainThreadHandle)
{
Memory.Manager.Map(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal, AMemoryPerm.RW);
Memory.Manager.MapDirectRW(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal);
//MainThreadHandle
WriteConfigEntry(Memory, ref Position, 1, 0, MainThreadHandle);

View file

@ -47,11 +47,11 @@ namespace Ryujinx.Core.OsHle
Processes = new ConcurrentDictionary<int, Process>();
HidSharedMem = new HSharedMem();
HidSharedMem = new HSharedMem(Ns.Hid.PA);
HidHandle = Handles.GenerateId(HidSharedMem);
FontHandle = Handles.GenerateId(new HSharedMem());
FontHandle = Handles.GenerateId(new HSharedMem(0x5000));
}
public void LoadCart(string ExeFsDir, string RomFsFile = null)

View file

@ -217,16 +217,26 @@ namespace Ryujinx.Core.OsHle.Ipc
public long GetSendBuffPtr()
{
if (SendBuff.Count > 0 && SendBuff[0].Position != 0)
if (SendBuff.Count > 0 && SendBuff[0].Size != 0)
{
return SendBuff[0].Position;
}
if (PtrBuff.Count > 0 && PtrBuff[0].Position != 0)
if (PtrBuff.Count > 0 && PtrBuff[0].Size != 0)
{
return PtrBuff[0].Position;
}
if (ReceiveBuff.Count > 0 && ReceiveBuff[0].Size != 0)
{
return ReceiveBuff[0].Position;
}
if (RecvListBuff.Count > 0 && RecvListBuff[0].Size != 0)
{
return RecvListBuff[0].Position;
}
return -1;
}
}

View file

@ -1,17 +1,18 @@
using ChocolArm64.Memory;
namespace Ryujinx.Core.OsHle
{
static class MemoryRegions
{
public const long RamSize = 1L << 32;
public const long AddrSpaceStart = 0x08000000;
public const int AddrSpaceBits = 38;
public const long AddrSpaceSize = 1L << AddrSpaceBits;
public const long MapRegionAddress = 0x10000000;
public const long MapRegionSize = 0x20000000;
public const long MainStackSize = 0x100000;
public const long MainStackAddress = AMemoryMgr.AddrSize - MainStackSize;
public const long MainStackAddress = RamSize - MainStackSize;
public const long TlsPagesSize = 0x4000;
@ -21,8 +22,8 @@ namespace Ryujinx.Core.OsHle
public const long TotalMemoryUsed = HeapRegionAddress + TlsPagesSize + MainStackSize;
public const long TotalMemoryAvailable = AMemoryMgr.RamSize - AddrSpaceStart;
public const long TotalMemoryAvailable = RamSize - AddrSpaceStart;
public const long AddrSpaceSize = AMemoryMgr.AddrSize - AddrSpaceStart;
}
}

View file

@ -45,7 +45,7 @@ namespace Ryujinx.Core.OsHle
this.Ns = Ns;
this.ProcessId = ProcessId;
Memory = new AMemory(Ns.Ram);
Memory = new AMemory(Ns.Ram, MemoryRegions.RamSize, MemoryRegions.AddrSpaceBits);
Scheduler = new KProcessScheduler();
@ -59,10 +59,10 @@ namespace Ryujinx.Core.OsHle
ImageBase = MemoryRegions.AddrSpaceStart;
MapRWMemRegion(
Memory.Manager.MapDirectRW(
MemoryRegions.TlsPagesAddress,
MemoryRegions.TlsPagesSize,
MemoryType.ThreadLocal);
(int)MemoryType.ThreadLocal);
}
public void LoadProgram(IExecutable Program)
@ -88,10 +88,10 @@ namespace Ryujinx.Core.OsHle
return false;
}
MapRWMemRegion(
Memory.Manager.MapDirectRW(
MemoryRegions.MainStackAddress,
MemoryRegions.MainStackSize,
MemoryType.Normal);
(int)MemoryType.Normal);
long StackTop = MemoryRegions.MainStackAddress + MemoryRegions.MainStackSize;
@ -119,11 +119,6 @@ namespace Ryujinx.Core.OsHle
return true;
}
private void MapRWMemRegion(long Position, long Size, MemoryType Type)
{
Memory.Manager.Map(Position, Size, (int)Type, AMemoryPerm.RW);
}
public void StopAllThreads()
{
if (MainThread != null)

View file

@ -81,7 +81,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
FileDesc FdData = Context.Ns.Os.Fds.GetData<FileDesc>(Fd);
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
Context.ResponseData.Write(0);
@ -139,7 +139,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuAsIoctlBindChannel(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
int Fd = Context.Memory.ReadInt32(Position);
@ -148,7 +148,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuAsIoctlAllocSpace(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
@ -174,7 +174,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuAsIoctlMapBufferEx(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
@ -207,7 +207,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuAsIoctlGetVaRegions(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
MemWriter Writer = new MemWriter(Context.Memory, Position);
@ -237,7 +237,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuAsIoctlInitializeEx(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
@ -254,7 +254,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvHostIoctlCtrlGetConfig(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
MemWriter Writer = new MemWriter(Context.Memory, Position + 0x82);
@ -269,7 +269,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvHostIoctlCtrlEventWait(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
@ -285,7 +285,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
Context.Memory.WriteInt32(Position, 1);
@ -294,7 +294,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuIoctlZcullGetInfo(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemWriter Writer = new MemWriter(Context.Memory, Position);
@ -314,7 +314,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuIoctlGetCharacteristics(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
MemWriter Writer = new MemWriter(Context.Memory, Position);
@ -376,7 +376,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuIoctlGetTpcMasks(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
@ -390,7 +390,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
Context.Memory.WriteInt32(Position + 0, 7);
Context.Memory.WriteInt32(Position + 4, 1);
@ -400,14 +400,14 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvMapIoctlChannelSetUserData(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
return 0;
}
private static long NvMapIoctlChannelSetNvMap(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
int Fd = Context.Memory.ReadInt32(Position);
@ -416,7 +416,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
MemWriter Writer = new MemWriter(Context.Memory, Position + 0x10);
@ -455,7 +455,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
int ClassNum = Context.Memory.ReadInt32(Position + 0);
int Flags = Context.Memory.ReadInt32(Position + 4);
@ -467,7 +467,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvMapIoctlChannelZcullBind(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
@ -480,7 +480,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
@ -494,7 +494,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvMapIoctlChannelSetPriority(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
int Priority = Context.Memory.ReadInt32(Position);
@ -503,7 +503,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private static long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context)
{
long Position = Context.Request.PtrBuff[0].Position;
long Position = Context.Request.GetSendBuffPtr();
MemReader Reader = new MemReader(Context.Memory, Position);
MemWriter Writer = new MemWriter(Context.Memory, Position + 0xc);

View file

@ -268,7 +268,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
HNvMap NvMap = GetNvMap(Context, Slot);
if (FbSize < 0 || NvMap.Address < 0 || NvMap.Address + FbSize > AMemoryMgr.AddrSize)
if (FbSize < 0 || NvMap.Address < 0 || NvMap.Address + FbSize > MemoryRegions.AddrSpaceSize)
{
Logging.Error($"Frame buffer address {NvMap.Address:x16} is invalid!");

View file

@ -16,7 +16,7 @@ namespace Ryujinx.Core.OsHle.Svc
if (Size > CurrentHeapSize)
{
Memory.Manager.Map(Position, Size, (int)MemoryType.Heap, AMemoryPerm.RW);
Memory.Manager.MapDirectRW(Position, Size, (int)MemoryType.Heap);
}
else
{
@ -57,7 +57,9 @@ namespace Ryujinx.Core.OsHle.Svc
AMemoryMapInfo SrcInfo = Memory.Manager.GetMapInfo(Src);
Memory.Manager.Map(Dst, Size, (int)MemoryType.MappedMemory, SrcInfo.Perm);
long PA = Memory.Manager.TranslatePosition(Src);
Memory.Manager.Map(Dst, PA, Size, (int)MemoryType.MappedMemory, SrcInfo.Perm);
Memory.Manager.Reprotect(Src, Size, AMemoryPerm.None);
@ -122,11 +124,9 @@ namespace Ryujinx.Core.OsHle.Svc
if (SharedMem != null)
{
AMemoryHelper.FillWithZeros(Memory, Src, (int)Size);
long PA = SharedMem.PA;
SharedMem.AddVirtualPosition(Src);
Memory.Manager.Map(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm);
Memory.Manager.Map(Src, PA, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm);
ThreadState.X0 = 0;
}

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Diagnostics;
using System.Timers;
namespace Ryujinx.Core

View file

@ -1,4 +1,3 @@
using ChocolArm64.Memory;
using Ryujinx.Core.Input;
using Ryujinx.Core.OsHle;
using Ryujinx.Core.Settings;
@ -25,21 +24,18 @@ namespace Ryujinx.Core
public Switch(IGalRenderer Renderer)
{
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
Ram = Marshal.AllocHGlobal((IntPtr)MemoryRegions.RamSize);
Gpu = new NsGpu(Renderer);
VFs = new VirtualFs();
Hid = new Hid(Ram);
Hid = new Hid(Ram, 0);
Statistics = new PerformanceStatistics();
Os = new Horizon(this);
Os.HidSharedMem.MemoryMapped += Hid.ShMemMap;
Os.HidSharedMem.MemoryUnmapped += Hid.ShMemUnmap;
Settings = new SetSys();
}

View file

@ -28,10 +28,12 @@ namespace Ryujinx.Tests.Cpu
EntryPoint = Position;
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
long RamSize = 32 * 1024 * 1024;
Ram = Marshal.AllocHGlobal((IntPtr)RamSize);
ATranslator Translator = new ATranslator();
Memory = new AMemory(Ram);
Memory.Manager.Map(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
Memory = new AMemory(Ram, RamSize, 32);
Memory.Manager.MapDirectRW(Position, Size, 2);
Thread = new AThread(Translator, Memory, ThreadPriority.Normal, EntryPoint);
}