Change long -> ulong for address/size on memory related methods to avoid unnecessary casts
This commit is contained in:
parent
c619596e07
commit
70e42d43d3
27 changed files with 683 additions and 655 deletions
|
@ -7,6 +7,11 @@ namespace Ryujinx.Common
|
||||||
return (Value + (Size - 1)) & -Size;
|
return (Value + (Size - 1)) & -Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ulong AlignUp(ulong Value, int Size)
|
||||||
|
{
|
||||||
|
return (ulong)AlignUp((long)Value, Size);
|
||||||
|
}
|
||||||
|
|
||||||
public static long AlignUp(long Value, int Size)
|
public static long AlignUp(long Value, int Size)
|
||||||
{
|
{
|
||||||
return (Value + (Size - 1)) & -(long)Size;
|
return (Value + (Size - 1)) & -(long)Size;
|
||||||
|
@ -17,11 +22,21 @@ namespace Ryujinx.Common
|
||||||
return Value & -Size;
|
return Value & -Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ulong AlignDown(ulong Value, int Size)
|
||||||
|
{
|
||||||
|
return (ulong)AlignDown((long)Value, Size);
|
||||||
|
}
|
||||||
|
|
||||||
public static long AlignDown(long Value, int Size)
|
public static long AlignDown(long Value, int Size)
|
||||||
{
|
{
|
||||||
return Value & -(long)Size;
|
return Value & -(long)Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ulong DivRoundUp(ulong Value, uint Dividend)
|
||||||
|
{
|
||||||
|
return (Value + Dividend - 1) / Dividend;
|
||||||
|
}
|
||||||
|
|
||||||
public static long DivRoundUp(long Value, int Dividend)
|
public static long DivRoundUp(long Value, int Dividend)
|
||||||
{
|
{
|
||||||
return (Value + Dividend - 1) / Dividend;
|
return (Value + Dividend - 1) / Dividend;
|
||||||
|
|
|
@ -25,9 +25,9 @@ namespace Ryujinx.HLE.HOS
|
||||||
internal const int HidSize = 0x40000;
|
internal const int HidSize = 0x40000;
|
||||||
internal const int FontSize = 0x1100000;
|
internal const int FontSize = 0x1100000;
|
||||||
|
|
||||||
private const long UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
|
private const ulong UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
|
||||||
private const long UserSlabHeapItemSize = KMemoryManager.PageSize;
|
private const ulong UserSlabHeapItemSize = KMemoryManager.PageSize;
|
||||||
private const long UserSlabHeapSize = 0x3de000;
|
private const ulong UserSlabHeapSize = 0x3de000;
|
||||||
|
|
||||||
internal Switch Device { get; private set; }
|
internal Switch Device { get; private set; }
|
||||||
|
|
||||||
|
@ -114,10 +114,10 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
KMemoryRegionManager Region = MemoryRegions[(int)MemoryRegion.Service];
|
KMemoryRegionManager Region = MemoryRegions[(int)MemoryRegion.Service];
|
||||||
|
|
||||||
long HidPa = Region.Address;
|
ulong HidPa = Region.Address;
|
||||||
long FontPa = Region.Address + HidSize;
|
ulong FontPa = Region.Address + HidSize;
|
||||||
|
|
||||||
HidBaseAddress = HidPa - DramMemoryMap.DramBase;
|
HidBaseAddress = (long)(HidPa - DramMemoryMap.DramBase);
|
||||||
|
|
||||||
KPageList HidPageList = new KPageList();
|
KPageList HidPageList = new KPageList();
|
||||||
KPageList FontPageList = new KPageList();
|
KPageList FontPageList = new KPageList();
|
||||||
|
@ -132,7 +132,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
AppletState.SetFocus(true);
|
AppletState.SetFocus(true);
|
||||||
|
|
||||||
Font = new SharedFontManager(Device, FontPa - DramMemoryMap.DramBase);
|
Font = new SharedFontManager(Device, (long)(FontPa - DramMemoryMap.DramBase));
|
||||||
|
|
||||||
VsyncEvent = new KEvent(this);
|
VsyncEvent = new KEvent(this);
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,14 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
static class DramMemoryMap
|
static class DramMemoryMap
|
||||||
{
|
{
|
||||||
public const long DramBase = 0x80000000;
|
public const ulong DramBase = 0x80000000;
|
||||||
public const long DramSize = 0x100000000;
|
public const ulong DramSize = 0x100000000;
|
||||||
public const long DramEnd = DramBase + DramSize;
|
public const ulong DramEnd = DramBase + DramSize;
|
||||||
|
|
||||||
public const long KernelReserveBase = DramBase + 0x60000;
|
public const ulong KernelReserveBase = DramBase + 0x60000;
|
||||||
|
|
||||||
public const long SlabHeapBase = KernelReserveBase + 0x85000;
|
public const ulong SlabHeapBase = KernelReserveBase + 0x85000;
|
||||||
public const long SlapHeapSize = 0xa21000;
|
public const ulong SlapHeapSize = 0xa21000;
|
||||||
public const long SlabHeapEnd = SlabHeapBase + SlapHeapSize;
|
public const ulong SlabHeapEnd = SlabHeapBase + SlapHeapSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -196,10 +196,10 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private void ScanMemoryForTextSegments()
|
private void ScanMemoryForTextSegments()
|
||||||
{
|
{
|
||||||
long OldAddress = 0;
|
ulong OldAddress = 0;
|
||||||
long Address = 0;
|
ulong Address = 0;
|
||||||
|
|
||||||
while ((ulong)Address >= (ulong)OldAddress)
|
while (Address >= OldAddress)
|
||||||
{
|
{
|
||||||
KMemoryInfo Info = Owner.MemoryManager.QueryMemory(Address);
|
KMemoryInfo Info = Owner.MemoryManager.QueryMemory(Address);
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
if (Info.State == MemoryState.CodeStatic && Info.Permission == MemoryPermission.ReadAndExecute)
|
if (Info.State == MemoryState.CodeStatic && Info.Permission == MemoryPermission.ReadAndExecute)
|
||||||
{
|
{
|
||||||
LoadMod0Symbols(Owner.CpuMemory, Info.Address);
|
LoadMod0Symbols(Owner.CpuMemory, (long)Info.Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
OldAddress = Address;
|
OldAddress = Address;
|
||||||
|
|
|
@ -2,12 +2,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
struct KMemoryArrangeRegion
|
struct KMemoryArrangeRegion
|
||||||
{
|
{
|
||||||
public long Address { get; private set; }
|
public ulong Address { get; private set; }
|
||||||
public long Size { get; private set; }
|
public ulong Size { get; private set; }
|
||||||
|
|
||||||
public long EndAddr => Address + Size;
|
public ulong EndAddr => Address + Size;
|
||||||
|
|
||||||
public KMemoryArrangeRegion(long Address, long Size)
|
public KMemoryArrangeRegion(ulong Address, ulong Size)
|
||||||
{
|
{
|
||||||
this.Address = Address;
|
this.Address = Address;
|
||||||
this.Size = Size;
|
this.Size = Size;
|
||||||
|
|
|
@ -2,8 +2,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
class KMemoryBlock
|
class KMemoryBlock
|
||||||
{
|
{
|
||||||
public long BaseAddress { get; set; }
|
public ulong BaseAddress { get; set; }
|
||||||
public long PagesCount { get; set; }
|
public ulong PagesCount { get; set; }
|
||||||
|
|
||||||
public MemoryState State { get; set; }
|
public MemoryState State { get; set; }
|
||||||
public MemoryPermission Permission { get; set; }
|
public MemoryPermission Permission { get; set; }
|
||||||
|
@ -13,8 +13,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
public int DeviceRefCount { get; set; }
|
public int DeviceRefCount { get; set; }
|
||||||
|
|
||||||
public KMemoryBlock(
|
public KMemoryBlock(
|
||||||
long BaseAddress,
|
ulong BaseAddress,
|
||||||
long PagesCount,
|
ulong PagesCount,
|
||||||
MemoryState State,
|
MemoryState State,
|
||||||
MemoryPermission Permission,
|
MemoryPermission Permission,
|
||||||
MemoryAttribute Attribute)
|
MemoryAttribute Attribute)
|
||||||
|
@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
public KMemoryInfo GetInfo()
|
public KMemoryInfo GetInfo()
|
||||||
{
|
{
|
||||||
long Size = PagesCount * KMemoryManager.PageSize;
|
ulong Size = PagesCount * KMemoryManager.PageSize;
|
||||||
|
|
||||||
return new KMemoryInfo(
|
return new KMemoryInfo(
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
|
|
|
@ -2,8 +2,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
class KMemoryInfo
|
class KMemoryInfo
|
||||||
{
|
{
|
||||||
public long Address { get; private set; }
|
public ulong Address { get; private set; }
|
||||||
public long Size { get; private set; }
|
public ulong Size { get; private set; }
|
||||||
|
|
||||||
public MemoryState State { get; private set; }
|
public MemoryState State { get; private set; }
|
||||||
public MemoryPermission Permission { get; private set; }
|
public MemoryPermission Permission { get; private set; }
|
||||||
|
@ -13,8 +13,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
public int DeviceRefCount { get; private set; }
|
public int DeviceRefCount { get; private set; }
|
||||||
|
|
||||||
public KMemoryInfo(
|
public KMemoryInfo(
|
||||||
long Address,
|
ulong Address,
|
||||||
long Size,
|
ulong Size,
|
||||||
MemoryState State,
|
MemoryState State,
|
||||||
MemoryPermission Permission,
|
MemoryPermission Permission,
|
||||||
MemoryAttribute Attribute,
|
MemoryAttribute Attribute,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,11 +4,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
public long[][] Masks;
|
public long[][] Masks;
|
||||||
|
|
||||||
public long FreeCount;
|
public ulong FreeCount;
|
||||||
public int MaxLevel;
|
public int MaxLevel;
|
||||||
public long StartAligned;
|
public ulong StartAligned;
|
||||||
public long SizeInBlocksTruncated;
|
public ulong SizeInBlocksTruncated;
|
||||||
public long SizeInBlocksRounded;
|
public ulong SizeInBlocksRounded;
|
||||||
public int Order;
|
public int Order;
|
||||||
public int NextOrder;
|
public int NextOrder;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeCount -= Size;
|
FreeCount -= (ulong)Size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,15 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
private static readonly int[] BlockOrders = new int[] { 12, 16, 21, 22, 25, 29, 30 };
|
private static readonly int[] BlockOrders = new int[] { 12, 16, 21, 22, 25, 29, 30 };
|
||||||
|
|
||||||
public long Address { get; private set; }
|
public ulong Address { get; private set; }
|
||||||
public long EndAddr { get; private set; }
|
public ulong EndAddr { get; private set; }
|
||||||
public long Size { get; private set; }
|
public ulong Size { get; private set; }
|
||||||
|
|
||||||
private int BlockOrdersCount;
|
private int BlockOrdersCount;
|
||||||
|
|
||||||
private KMemoryRegionBlock[] Blocks;
|
private KMemoryRegionBlock[] Blocks;
|
||||||
|
|
||||||
public KMemoryRegionManager(long Address, long Size, long EndAddr)
|
public KMemoryRegionManager(ulong Address, ulong Size, ulong EndAddr)
|
||||||
{
|
{
|
||||||
Blocks = new KMemoryRegionBlock[BlockOrders.Length];
|
Blocks = new KMemoryRegionBlock[BlockOrders.Length];
|
||||||
|
|
||||||
|
@ -42,18 +42,18 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
NextBlockSize = 1 << NextOrder;
|
NextBlockSize = 1 << NextOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
long StartAligned = BitUtils.AlignDown(Address, NextBlockSize);
|
ulong StartAligned = BitUtils.AlignDown(Address, NextBlockSize);
|
||||||
long EndAddrAligned = BitUtils.AlignDown(EndAddr, CurrBlockSize);
|
ulong EndAddrAligned = BitUtils.AlignDown(EndAddr, CurrBlockSize);
|
||||||
|
|
||||||
ulong SizeInBlocksTruncated = (ulong)(EndAddrAligned - StartAligned) >> BlockOrders[BlockIndex];
|
ulong SizeInBlocksTruncated = (EndAddrAligned - StartAligned) >> BlockOrders[BlockIndex];
|
||||||
|
|
||||||
long EndAddrRounded = BitUtils.AlignUp(Address + Size, NextBlockSize);
|
ulong EndAddrRounded = BitUtils.AlignUp(Address + Size, NextBlockSize);
|
||||||
|
|
||||||
ulong SizeInBlocksRounded = (ulong)(EndAddrRounded - StartAligned) >> BlockOrders[BlockIndex];
|
ulong SizeInBlocksRounded = (EndAddrRounded - StartAligned) >> BlockOrders[BlockIndex];
|
||||||
|
|
||||||
Blocks[BlockIndex].StartAligned = StartAligned;
|
Blocks[BlockIndex].StartAligned = StartAligned;
|
||||||
Blocks[BlockIndex].SizeInBlocksTruncated = (long)SizeInBlocksTruncated;
|
Blocks[BlockIndex].SizeInBlocksTruncated = SizeInBlocksTruncated;
|
||||||
Blocks[BlockIndex].SizeInBlocksRounded = (long)SizeInBlocksRounded;
|
Blocks[BlockIndex].SizeInBlocksRounded = SizeInBlocksRounded;
|
||||||
|
|
||||||
ulong CurrSizeInBlocks = SizeInBlocksRounded;
|
ulong CurrSizeInBlocks = SizeInBlocksRounded;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public KernelResult AllocatePages(long PagesCount, bool Backwards, out KPageList PageList)
|
public KernelResult AllocatePages(ulong PagesCount, bool Backwards, out KPageList PageList)
|
||||||
{
|
{
|
||||||
lock (Blocks)
|
lock (Blocks)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private KernelResult AllocatePagesImpl(long PagesCount, bool Backwards, out KPageList PageList)
|
private KernelResult AllocatePagesImpl(ulong PagesCount, bool Backwards, out KPageList PageList)
|
||||||
{
|
{
|
||||||
Backwards = false;
|
Backwards = false;
|
||||||
|
|
||||||
|
@ -109,10 +109,10 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
ulong BlockPagesCount = (1UL << Block.Order) / KMemoryManager.PageSize;
|
ulong BlockPagesCount = (1UL << Block.Order) / KMemoryManager.PageSize;
|
||||||
|
|
||||||
AvailablePages += BlockPagesCount * (ulong)Block.FreeCount;
|
AvailablePages += BlockPagesCount * Block.FreeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AvailablePages < (ulong)PagesCount)
|
if (AvailablePages < PagesCount)
|
||||||
{
|
{
|
||||||
return KernelResult.OutOfMemory;
|
return KernelResult.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
@ -126,15 +126,15 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
KMemoryRegionBlock Block = Blocks[BlockIndex];
|
KMemoryRegionBlock Block = Blocks[BlockIndex];
|
||||||
|
|
||||||
int BestFitBlockSize = 1 << Block.Order;
|
ulong BestFitBlockSize = 1UL << Block.Order;
|
||||||
|
|
||||||
int BlockPagesCount = BestFitBlockSize / KMemoryManager.PageSize;
|
ulong BlockPagesCount = BestFitBlockSize / KMemoryManager.PageSize;
|
||||||
|
|
||||||
//Check if this is the best fit for this page size.
|
//Check if this is the best fit for this page size.
|
||||||
//If so, try allocating as much requested pages as possible.
|
//If so, try allocating as much requested pages as possible.
|
||||||
while ((ulong)BlockPagesCount <= (ulong)PagesCount)
|
while (BlockPagesCount <= PagesCount)
|
||||||
{
|
{
|
||||||
long Address = 0;
|
ulong Address = 0;
|
||||||
|
|
||||||
for (int CurrBlockIndex = BlockIndex;
|
for (int CurrBlockIndex = BlockIndex;
|
||||||
CurrBlockIndex < BlockOrdersCount && Address == 0;
|
CurrBlockIndex < BlockOrdersCount && Address == 0;
|
||||||
|
@ -167,7 +167,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
|
if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Address = Block.StartAligned + ((long)Index << Block.Order);
|
Address = Block.StartAligned + ((ulong)Index << Block.Order);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int CurrBlockIndex = BlockIndex;
|
for (int CurrBlockIndex = BlockIndex;
|
||||||
|
@ -220,7 +220,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
|
if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Address = Block.StartAligned + ((long)Index << Block.Order);
|
Address = Block.StartAligned + ((ulong)Index << Block.Order);
|
||||||
}
|
}
|
||||||
|
|
||||||
//The address being zero means that no free space was found on that order,
|
//The address being zero means that no free space was found on that order,
|
||||||
|
@ -251,7 +251,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
//If we are using a larger order than best fit, then we should
|
//If we are using a larger order than best fit, then we should
|
||||||
//split it into smaller blocks.
|
//split it into smaller blocks.
|
||||||
int FirstFreeBlockSize = 1 << Block.Order;
|
ulong FirstFreeBlockSize = 1UL << Block.Order;
|
||||||
|
|
||||||
if (FirstFreeBlockSize > BestFitBlockSize)
|
if (FirstFreeBlockSize > BestFitBlockSize)
|
||||||
{
|
{
|
||||||
|
@ -304,32 +304,31 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FreePages(long Address, long PagesCount)
|
private void FreePages(ulong Address, ulong PagesCount)
|
||||||
{
|
{
|
||||||
long EndAddr = Address + PagesCount * KMemoryManager.PageSize;
|
ulong EndAddr = Address + PagesCount * KMemoryManager.PageSize;
|
||||||
|
|
||||||
int BlockIndex = BlockOrdersCount - 1;
|
int BlockIndex = BlockOrdersCount - 1;
|
||||||
|
|
||||||
long AddressRounded = 0;
|
ulong AddressRounded = 0;
|
||||||
long EndAddrTruncated = 0;
|
ulong EndAddrTruncated = 0;
|
||||||
|
|
||||||
for (; BlockIndex >= 0; BlockIndex--)
|
for (; BlockIndex >= 0; BlockIndex--)
|
||||||
{
|
{
|
||||||
KMemoryRegionBlock AllocInfo = Blocks[BlockIndex];
|
KMemoryRegionBlock AllocInfo = Blocks[BlockIndex];
|
||||||
|
|
||||||
long BlockSize = 1L << AllocInfo.Order;
|
int BlockSize = 1 << AllocInfo.Order;
|
||||||
|
|
||||||
AddressRounded = (Address + BlockSize - 1) & -BlockSize;
|
AddressRounded = BitUtils.AlignUp (Address, BlockSize);
|
||||||
|
EndAddrTruncated = BitUtils.AlignDown(EndAddr, BlockSize);
|
||||||
|
|
||||||
EndAddrTruncated = EndAddr & -BlockSize;
|
if (AddressRounded < EndAddrTruncated)
|
||||||
|
|
||||||
if ((ulong)AddressRounded < (ulong)EndAddrTruncated)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeRegion(long CurrAddress)
|
void FreeRegion(ulong CurrAddress)
|
||||||
{
|
{
|
||||||
for (int CurrBlockIndex = BlockIndex;
|
for (int CurrBlockIndex = BlockIndex;
|
||||||
CurrBlockIndex < BlockOrdersCount && CurrAddress != 0;
|
CurrBlockIndex < BlockOrdersCount && CurrAddress != 0;
|
||||||
|
@ -339,7 +338,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
Block.FreeCount++;
|
Block.FreeCount++;
|
||||||
|
|
||||||
ulong FreedBlocks = (ulong)(CurrAddress - Block.StartAligned) >> Block.Order;
|
ulong FreedBlocks = (CurrAddress - Block.StartAligned) >> Block.Order;
|
||||||
|
|
||||||
int Index = (int)FreedBlocks;
|
int Index = (int)FreedBlocks;
|
||||||
|
|
||||||
|
@ -357,23 +356,23 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
int BlockSizeDelta = 1 << (Block.NextOrder - Block.Order);
|
int BlockSizeDelta = 1 << (Block.NextOrder - Block.Order);
|
||||||
|
|
||||||
int FreedBlocksTruncated = (int)FreedBlocks & -BlockSizeDelta;
|
int FreedBlocksTruncated = BitUtils.AlignDown((int)FreedBlocks, BlockSizeDelta);
|
||||||
|
|
||||||
if (!Block.TryCoalesce(FreedBlocksTruncated, BlockSizeDelta))
|
if (!Block.TryCoalesce(FreedBlocksTruncated, BlockSizeDelta))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrAddress = Block.StartAligned + ((long)FreedBlocksTruncated << Block.Order);
|
CurrAddress = Block.StartAligned + ((ulong)FreedBlocksTruncated << Block.Order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Free inside aligned region.
|
//Free inside aligned region.
|
||||||
long BaseAddress = AddressRounded;
|
ulong BaseAddress = AddressRounded;
|
||||||
|
|
||||||
while ((ulong)BaseAddress < (ulong)EndAddrTruncated)
|
while (BaseAddress < EndAddrTruncated)
|
||||||
{
|
{
|
||||||
long BlockSize = 1L << Blocks[BlockIndex].Order;
|
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
|
||||||
|
|
||||||
FreeRegion(BaseAddress);
|
FreeRegion(BaseAddress);
|
||||||
|
|
||||||
|
@ -387,9 +386,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
|
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
|
||||||
{
|
{
|
||||||
long BlockSize = 1L << Blocks[BlockIndex].Order;
|
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
|
||||||
|
|
||||||
while ((ulong)(BaseAddress - BlockSize) >= (ulong)Address)
|
while (BaseAddress - BlockSize >= Address)
|
||||||
{
|
{
|
||||||
BaseAddress -= BlockSize;
|
BaseAddress -= BlockSize;
|
||||||
|
|
||||||
|
@ -402,9 +401,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
|
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
|
||||||
{
|
{
|
||||||
long BlockSize = 1L << Blocks[BlockIndex].Order;
|
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
|
||||||
|
|
||||||
while ((ulong)(BaseAddress + BlockSize) <= (ulong)EndAddr)
|
while (BaseAddress + BlockSize <= EndAddr)
|
||||||
{
|
{
|
||||||
FreeRegion(BaseAddress);
|
FreeRegion(BaseAddress);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
Nodes = new LinkedList<KPageNode>();
|
Nodes = new LinkedList<KPageNode>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KernelResult AddRange(long Address, long PagesCount)
|
public KernelResult AddRange(ulong Address, ulong PagesCount)
|
||||||
{
|
{
|
||||||
if (PagesCount != 0)
|
if (PagesCount != 0)
|
||||||
{
|
{
|
||||||
|
@ -35,9 +35,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return KernelResult.Success;
|
return KernelResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetPagesCount()
|
public ulong GetPagesCount()
|
||||||
{
|
{
|
||||||
long Sum = 0;
|
ulong Sum = 0;
|
||||||
|
|
||||||
foreach (KPageNode Node in Nodes)
|
foreach (KPageNode Node in Nodes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,10 +2,10 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
struct KPageNode
|
struct KPageNode
|
||||||
{
|
{
|
||||||
public long Address;
|
public ulong Address;
|
||||||
public long PagesCount;
|
public ulong PagesCount;
|
||||||
|
|
||||||
public KPageNode(long Address, long PagesCount)
|
public KPageNode(ulong Address, ulong PagesCount)
|
||||||
{
|
{
|
||||||
this.Address = Address;
|
this.Address = Address;
|
||||||
this.PagesCount = PagesCount;
|
this.PagesCount = PagesCount;
|
||||||
|
|
|
@ -21,10 +21,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
public KMemoryManager MemoryManager { get; private set; }
|
public KMemoryManager MemoryManager { get; private set; }
|
||||||
|
|
||||||
private long TotalMemoryUsage;
|
private SortedDictionary<ulong, KTlsPageInfo> FullTlsPages;
|
||||||
|
private SortedDictionary<ulong, KTlsPageInfo> FreeTlsPages;
|
||||||
private SortedDictionary<long, KTlsPageInfo> FullTlsPages;
|
|
||||||
private SortedDictionary<long, KTlsPageInfo> FreeTlsPages;
|
|
||||||
|
|
||||||
public int DefaultCpuCore { get; private set; }
|
public int DefaultCpuCore { get; private set; }
|
||||||
|
|
||||||
|
@ -32,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
public KResourceLimit ResourceLimit { get; private set; }
|
public KResourceLimit ResourceLimit { get; private set; }
|
||||||
|
|
||||||
public long PersonalMmHeapPagesCount { get; private set; }
|
public ulong PersonalMmHeapPagesCount { get; private set; }
|
||||||
|
|
||||||
private ProcessState State;
|
private ProcessState State;
|
||||||
|
|
||||||
|
@ -60,15 +58,15 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
public long Pid { get; private set; }
|
public long Pid { get; private set; }
|
||||||
|
|
||||||
private long CreationTimestamp;
|
private long CreationTimestamp;
|
||||||
private long Entrypoint;
|
private ulong Entrypoint;
|
||||||
private long ImageSize;
|
private ulong ImageSize;
|
||||||
private long MainThreadStackSize;
|
private ulong MainThreadStackSize;
|
||||||
private long MemoryUsageCapacity;
|
private ulong MemoryUsageCapacity;
|
||||||
private int Category;
|
private int Category;
|
||||||
|
|
||||||
public KHandleTable HandleTable { get; private set; }
|
public KHandleTable HandleTable { get; private set; }
|
||||||
|
|
||||||
public long UserExceptionContextAddress { get; private set; }
|
public ulong UserExceptionContextAddress { get; private set; }
|
||||||
|
|
||||||
private LinkedList<KThread> Threads;
|
private LinkedList<KThread> Threads;
|
||||||
|
|
||||||
|
@ -93,8 +91,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
MemoryManager = new KMemoryManager(System, CpuMemory);
|
MemoryManager = new KMemoryManager(System, CpuMemory);
|
||||||
|
|
||||||
FullTlsPages = new SortedDictionary<long, KTlsPageInfo>();
|
FullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
|
||||||
FreeTlsPages = new SortedDictionary<long, KTlsPageInfo>();
|
FreeTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
|
||||||
|
|
||||||
Capabilities = new KProcessCapabilities();
|
Capabilities = new KProcessCapabilities();
|
||||||
|
|
||||||
|
@ -122,9 +120,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;
|
bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;
|
||||||
|
|
||||||
long CodeAddress = CreationInfo.CodeAddress;
|
ulong CodeAddress = CreationInfo.CodeAddress;
|
||||||
|
|
||||||
long CodeSize = (long)(uint)CreationInfo.CodePagesCount * KMemoryManager.PageSize;
|
ulong CodeSize = (ulong)CreationInfo.CodePagesCount * KMemoryManager.PageSize;
|
||||||
|
|
||||||
KernelResult Result = MemoryManager.InitializeForProcess(
|
KernelResult Result = MemoryManager.InitializeForProcess(
|
||||||
AddrSpaceType,
|
AddrSpaceType,
|
||||||
|
@ -183,11 +181,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
this.ResourceLimit = ResourceLimit;
|
this.ResourceLimit = ResourceLimit;
|
||||||
this.MemRegion = MemRegion;
|
this.MemRegion = MemRegion;
|
||||||
|
|
||||||
long PersonalMmHeapSize = GetPersonalMmHeapSize(CreationInfo.PersonalMmHeapPagesCount, MemRegion);
|
ulong PersonalMmHeapSize = GetPersonalMmHeapSize((ulong)CreationInfo.PersonalMmHeapPagesCount, MemRegion);
|
||||||
|
|
||||||
long CodePagesCount = (long)(uint)CreationInfo.CodePagesCount;
|
ulong CodePagesCount = (ulong)CreationInfo.CodePagesCount;
|
||||||
|
|
||||||
long NeededSizeForProcess = PersonalMmHeapSize + CodePagesCount * KMemoryManager.PageSize;
|
ulong NeededSizeForProcess = PersonalMmHeapSize + CodePagesCount * KMemoryManager.PageSize;
|
||||||
|
|
||||||
if (NeededSizeForProcess != 0 && ResourceLimit != null)
|
if (NeededSizeForProcess != 0 && ResourceLimit != null)
|
||||||
{
|
{
|
||||||
|
@ -205,7 +203,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PersonalMmHeapPagesCount = CreationInfo.PersonalMmHeapPagesCount;
|
PersonalMmHeapPagesCount = (ulong)CreationInfo.PersonalMmHeapPagesCount;
|
||||||
|
|
||||||
if (PersonalMmHeapPagesCount != 0)
|
if (PersonalMmHeapPagesCount != 0)
|
||||||
{
|
{
|
||||||
|
@ -216,9 +214,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;
|
bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;
|
||||||
|
|
||||||
long CodeAddress = CreationInfo.CodeAddress;
|
ulong CodeAddress = CreationInfo.CodeAddress;
|
||||||
|
|
||||||
long CodeSize = CodePagesCount * KMemoryManager.PageSize;
|
ulong CodeSize = CodePagesCount * KMemoryManager.PageSize;
|
||||||
|
|
||||||
KernelResult Result = MemoryManager.InitializeForProcess(
|
KernelResult Result = MemoryManager.InitializeForProcess(
|
||||||
AddrSpaceType,
|
AddrSpaceType,
|
||||||
|
@ -281,10 +279,10 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateCodeAddressAndSize(long Address, long Size)
|
private bool ValidateCodeAddressAndSize(ulong Address, ulong Size)
|
||||||
{
|
{
|
||||||
long CodeRegionStart;
|
ulong CodeRegionStart;
|
||||||
long CodeRegionSize;
|
ulong CodeRegionSize;
|
||||||
|
|
||||||
switch (MemoryManager.AddrSpaceWidth)
|
switch (MemoryManager.AddrSpaceWidth)
|
||||||
{
|
{
|
||||||
|
@ -306,18 +304,18 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
default: throw new InvalidOperationException("Invalid address space width on memory manager.");
|
default: throw new InvalidOperationException("Invalid address space width on memory manager.");
|
||||||
}
|
}
|
||||||
|
|
||||||
long EndAddr = Address + Size;
|
ulong EndAddr = Address + Size;
|
||||||
|
|
||||||
long CodeRegionEnd = CodeRegionStart + CodeRegionSize;
|
ulong CodeRegionEnd = CodeRegionStart + CodeRegionSize;
|
||||||
|
|
||||||
if ((ulong)EndAddr <= (ulong)Address ||
|
if (EndAddr <= Address ||
|
||||||
(ulong)EndAddr - 1 > (ulong)CodeRegionEnd - 1)
|
EndAddr - 1 > CodeRegionEnd - 1)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MemoryManager.InsideHeapRegion(Address, Size) ||
|
if (MemoryManager.InsideHeapRegion(Address, Size) ||
|
||||||
MemoryManager.InsideMapRegion (Address, Size))
|
MemoryManager.InsideAliasRegion (Address, Size))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +344,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return KernelResult.InvalidCombination;
|
return KernelResult.InvalidCombination;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelResult Result = AllocateThreadLocalStorage(out long UserExceptionContextAddress);
|
KernelResult Result = AllocateThreadLocalStorage(out ulong UserExceptionContextAddress);
|
||||||
|
|
||||||
if (Result != KernelResult.Success)
|
if (Result != KernelResult.Success)
|
||||||
{
|
{
|
||||||
|
@ -355,7 +353,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
this.UserExceptionContextAddress = UserExceptionContextAddress;
|
this.UserExceptionContextAddress = UserExceptionContextAddress;
|
||||||
|
|
||||||
MemoryHelper.FillWithZeros(CpuMemory, UserExceptionContextAddress, KTlsPageInfo.TlsEntrySize);
|
MemoryHelper.FillWithZeros(CpuMemory, (long)UserExceptionContextAddress, KTlsPageInfo.TlsEntrySize);
|
||||||
|
|
||||||
Name = CreationInfo.Name;
|
Name = CreationInfo.Name;
|
||||||
|
|
||||||
|
@ -367,7 +365,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
Category = CreationInfo.Category;
|
Category = CreationInfo.Category;
|
||||||
TitleId = CreationInfo.TitleId;
|
TitleId = CreationInfo.TitleId;
|
||||||
Entrypoint = CreationInfo.CodeAddress;
|
Entrypoint = CreationInfo.CodeAddress;
|
||||||
ImageSize = CreationInfo.CodePagesCount * KMemoryManager.PageSize;
|
ImageSize = (ulong)CreationInfo.CodePagesCount * KMemoryManager.PageSize;
|
||||||
|
|
||||||
UseSystemMemBlocks = ((MmuFlags >> 6) & 1) != 0;
|
UseSystemMemBlocks = ((MmuFlags >> 6) & 1) != 0;
|
||||||
|
|
||||||
|
@ -395,7 +393,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return KernelResult.Success;
|
return KernelResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KernelResult AllocateThreadLocalStorage(out long Address)
|
public KernelResult AllocateThreadLocalStorage(out ulong Address)
|
||||||
{
|
{
|
||||||
System.CriticalSection.Enter();
|
System.CriticalSection.Enter();
|
||||||
|
|
||||||
|
@ -449,15 +447,15 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
PageInfo = default(KTlsPageInfo);
|
PageInfo = default(KTlsPageInfo);
|
||||||
|
|
||||||
if (!System.UserSlabHeapPages.TryGetItem(out long TlsPagePa))
|
if (!System.UserSlabHeapPages.TryGetItem(out ulong TlsPagePa))
|
||||||
{
|
{
|
||||||
return KernelResult.OutOfMemory;
|
return KernelResult.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
long RegionStart = MemoryManager.TlsIoRegionStart;
|
ulong RegionStart = MemoryManager.TlsIoRegionStart;
|
||||||
long RegionSize = MemoryManager.TlsIoRegionEnd - RegionStart;
|
ulong RegionSize = MemoryManager.TlsIoRegionEnd - RegionStart;
|
||||||
|
|
||||||
long RegionPagesCount = (long)((ulong)RegionSize / KMemoryManager.PageSize);
|
ulong RegionPagesCount = RegionSize / KMemoryManager.PageSize;
|
||||||
|
|
||||||
KernelResult Result = MemoryManager.AllocateOrMapPa(
|
KernelResult Result = MemoryManager.AllocateOrMapPa(
|
||||||
1,
|
1,
|
||||||
|
@ -468,7 +466,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
RegionPagesCount,
|
RegionPagesCount,
|
||||||
MemoryState.ThreadLocal,
|
MemoryState.ThreadLocal,
|
||||||
MemoryPermission.ReadAndWrite,
|
MemoryPermission.ReadAndWrite,
|
||||||
out long TlsPageVa);
|
out ulong TlsPageVa);
|
||||||
|
|
||||||
if (Result != KernelResult.Success)
|
if (Result != KernelResult.Success)
|
||||||
{
|
{
|
||||||
|
@ -478,15 +476,15 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
PageInfo = new KTlsPageInfo(TlsPageVa);
|
PageInfo = new KTlsPageInfo(TlsPageVa);
|
||||||
|
|
||||||
MemoryHelper.FillWithZeros(CpuMemory, TlsPageVa, KMemoryManager.PageSize);
|
MemoryHelper.FillWithZeros(CpuMemory, (long)TlsPageVa, KMemoryManager.PageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KernelResult FreeThreadLocalStorage(long TlsSlotAddr)
|
public KernelResult FreeThreadLocalStorage(ulong TlsSlotAddr)
|
||||||
{
|
{
|
||||||
long TlsPageAddr = BitUtils.AlignDown(TlsSlotAddr, KMemoryManager.PageSize);
|
ulong TlsPageAddr = BitUtils.AlignDown(TlsSlotAddr, KMemoryManager.PageSize);
|
||||||
|
|
||||||
System.CriticalSection.Enter();
|
System.CriticalSection.Enter();
|
||||||
|
|
||||||
|
@ -531,7 +529,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private KernelResult FreeTlsPage(KTlsPageInfo PageInfo)
|
private KernelResult FreeTlsPage(KTlsPageInfo PageInfo)
|
||||||
{
|
{
|
||||||
KernelResult Result = MemoryManager.ConvertVaToPa(PageInfo.PageAddr, out long TlsPagePa);
|
KernelResult Result = MemoryManager.ConvertVaToPa(PageInfo.PageAddr, out ulong TlsPagePa);
|
||||||
|
|
||||||
if (Result != KernelResult.Success)
|
if (Result != KernelResult.Success)
|
||||||
{
|
{
|
||||||
|
@ -553,7 +551,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
//TODO.
|
//TODO.
|
||||||
}
|
}
|
||||||
|
|
||||||
public KernelResult Start(int MainThreadPriority, long StackSize)
|
public KernelResult Start(int MainThreadPriority, ulong StackSize)
|
||||||
{
|
{
|
||||||
lock (ProcessLock)
|
lock (ProcessLock)
|
||||||
{
|
{
|
||||||
|
@ -575,15 +573,15 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
throw new InvalidOperationException("Trying to start a process with a invalid state!");
|
throw new InvalidOperationException("Trying to start a process with a invalid state!");
|
||||||
}
|
}
|
||||||
|
|
||||||
long StackSizeRounded = BitUtils.AlignUp(StackSize, KMemoryManager.PageSize);
|
ulong StackSizeRounded = BitUtils.AlignUp(StackSize, KMemoryManager.PageSize);
|
||||||
|
|
||||||
long NeededSize = StackSizeRounded + ImageSize;
|
ulong NeededSize = StackSizeRounded + ImageSize;
|
||||||
|
|
||||||
//Check if the needed size for the code and the stack will fit on the
|
//Check if the needed size for the code and the stack will fit on the
|
||||||
//memory usage capacity of this Process. Also check for possible overflow
|
//memory usage capacity of this Process. Also check for possible overflow
|
||||||
//on the above addition.
|
//on the above addition.
|
||||||
if ((ulong)NeededSize > (ulong)MemoryUsageCapacity ||
|
if (NeededSize > MemoryUsageCapacity ||
|
||||||
(ulong)NeededSize < (ulong)StackSizeRounded)
|
NeededSize < StackSizeRounded)
|
||||||
{
|
{
|
||||||
ThreadResourceLimit?.Release(LimitableResource.Thread, 1);
|
ThreadResourceLimit?.Release(LimitableResource.Thread, 1);
|
||||||
|
|
||||||
|
@ -606,7 +604,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
KThread MainThread = null;
|
KThread MainThread = null;
|
||||||
|
|
||||||
long StackTop = 0;
|
ulong StackTop = 0;
|
||||||
|
|
||||||
void CleanUpForError()
|
void CleanUpForError()
|
||||||
{
|
{
|
||||||
|
@ -615,9 +613,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
if (MainThreadStackSize != 0)
|
if (MainThreadStackSize != 0)
|
||||||
{
|
{
|
||||||
long StackBottom = StackTop - MainThreadStackSize;
|
ulong StackBottom = StackTop - MainThreadStackSize;
|
||||||
|
|
||||||
long StackPagesCount = (long)((ulong)MainThreadStackSize / KMemoryManager.PageSize);
|
ulong StackPagesCount = MainThreadStackSize / KMemoryManager.PageSize;
|
||||||
|
|
||||||
MemoryManager.UnmapForKernel(StackBottom, StackPagesCount, MemoryState.Stack);
|
MemoryManager.UnmapForKernel(StackBottom, StackPagesCount, MemoryState.Stack);
|
||||||
}
|
}
|
||||||
|
@ -628,12 +626,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
if (StackSizeRounded != 0)
|
if (StackSizeRounded != 0)
|
||||||
{
|
{
|
||||||
long StackPagesCount = (long)((ulong)StackSizeRounded / KMemoryManager.PageSize);
|
ulong StackPagesCount = StackSizeRounded / KMemoryManager.PageSize;
|
||||||
|
|
||||||
long RegionStart = MemoryManager.StackRegionStart;
|
ulong RegionStart = MemoryManager.StackRegionStart;
|
||||||
long RegionSize = MemoryManager.StackRegionEnd - RegionStart;
|
ulong RegionSize = MemoryManager.StackRegionEnd - RegionStart;
|
||||||
|
|
||||||
long RegionPagesCount = (long)((ulong)RegionSize / KMemoryManager.PageSize);
|
ulong RegionPagesCount = RegionSize / KMemoryManager.PageSize;
|
||||||
|
|
||||||
Result = MemoryManager.AllocateOrMapPa(
|
Result = MemoryManager.AllocateOrMapPa(
|
||||||
StackPagesCount,
|
StackPagesCount,
|
||||||
|
@ -644,7 +642,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
RegionPagesCount,
|
RegionPagesCount,
|
||||||
MemoryState.Stack,
|
MemoryState.Stack,
|
||||||
MemoryPermission.ReadAndWrite,
|
MemoryPermission.ReadAndWrite,
|
||||||
out long StackBottom);
|
out ulong StackBottom);
|
||||||
|
|
||||||
if (Result != KernelResult.Success)
|
if (Result != KernelResult.Success)
|
||||||
{
|
{
|
||||||
|
@ -658,7 +656,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
StackTop = StackBottom + StackSizeRounded;
|
StackTop = StackBottom + StackSizeRounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
long HeapCapacity = MemoryUsageCapacity - MainThreadStackSize - ImageSize;
|
ulong HeapCapacity = MemoryUsageCapacity - MainThreadStackSize - ImageSize;
|
||||||
|
|
||||||
Result = MemoryManager.SetHeapCapacity(HeapCapacity);
|
Result = MemoryManager.SetHeapCapacity(HeapCapacity);
|
||||||
|
|
||||||
|
@ -747,9 +745,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
public KernelResult InitializeThread(
|
public KernelResult InitializeThread(
|
||||||
KThread Thread,
|
KThread Thread,
|
||||||
long Entrypoint,
|
ulong Entrypoint,
|
||||||
long ArgsPtr,
|
ulong ArgsPtr,
|
||||||
long StackTop,
|
ulong StackTop,
|
||||||
int Priority,
|
int Priority,
|
||||||
int CpuCore)
|
int CpuCore)
|
||||||
{
|
{
|
||||||
|
@ -783,9 +781,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetMemoryCapacity()
|
public ulong GetMemoryCapacity()
|
||||||
{
|
{
|
||||||
long TotalCapacity = ResourceLimit.GetRemainingValue(LimitableResource.Memory);
|
ulong TotalCapacity = (ulong)ResourceLimit.GetRemainingValue(LimitableResource.Memory);
|
||||||
|
|
||||||
TotalCapacity += MemoryManager.GetTotalHeapSize();
|
TotalCapacity += MemoryManager.GetTotalHeapSize();
|
||||||
|
|
||||||
|
@ -793,7 +791,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
TotalCapacity += ImageSize + MainThreadStackSize;
|
TotalCapacity += ImageSize + MainThreadStackSize;
|
||||||
|
|
||||||
if ((ulong)TotalCapacity <= (ulong)MemoryUsageCapacity)
|
if (TotalCapacity <= MemoryUsageCapacity)
|
||||||
{
|
{
|
||||||
return TotalCapacity;
|
return TotalCapacity;
|
||||||
}
|
}
|
||||||
|
@ -801,28 +799,28 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return MemoryUsageCapacity;
|
return MemoryUsageCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetMemoryUsage()
|
public ulong GetMemoryUsage()
|
||||||
{
|
{
|
||||||
//TODO: Personal Mm Heap.
|
//TODO: Personal Mm Heap.
|
||||||
return ImageSize + MainThreadStackSize + MemoryManager.GetTotalHeapSize();
|
return ImageSize + MainThreadStackSize + MemoryManager.GetTotalHeapSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetMemoryCapacityWithoutPersonalMmHeap()
|
public ulong GetMemoryCapacityWithoutPersonalMmHeap()
|
||||||
{
|
{
|
||||||
return GetMemoryCapacity() - GetPersonalMmHeapSize();
|
return GetMemoryCapacity() - GetPersonalMmHeapSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetMemoryUsageWithoutPersonalMmHeap()
|
public ulong GetMemoryUsageWithoutPersonalMmHeap()
|
||||||
{
|
{
|
||||||
return GetMemoryUsage() - GetPersonalMmHeapSize();
|
return GetMemoryUsage() - GetPersonalMmHeapSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private long GetPersonalMmHeapSize()
|
private ulong GetPersonalMmHeapSize()
|
||||||
{
|
{
|
||||||
return GetPersonalMmHeapSize(PersonalMmHeapPagesCount, MemRegion);
|
return GetPersonalMmHeapSize(PersonalMmHeapPagesCount, MemRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long GetPersonalMmHeapSize(long PersonalMmHeapPagesCount, MemoryRegion MemRegion)
|
private static ulong GetPersonalMmHeapSize(ulong PersonalMmHeapPagesCount, MemoryRegion MemRegion)
|
||||||
{
|
{
|
||||||
if (MemRegion == MemoryRegion.Applet)
|
if (MemRegion == MemoryRegion.Applet)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
class KResourceLimit
|
class KResourceLimit
|
||||||
{
|
{
|
||||||
|
private const int Time10SecondsMs = 10000;
|
||||||
|
|
||||||
private long[] Current;
|
private long[] Current;
|
||||||
private long[] Limit;
|
private long[] Limit;
|
||||||
private long[] Available;
|
private long[] Available;
|
||||||
|
@ -30,10 +32,14 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
this.System = System;
|
this.System = System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Reserve(LimitableResource Resource, ulong Amount)
|
||||||
|
{
|
||||||
|
return Reserve(Resource, (long)Amount);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Reserve(LimitableResource Resource, long Amount)
|
public bool Reserve(LimitableResource Resource, long Amount)
|
||||||
{
|
{
|
||||||
//Wait 10 seconds for the resource if no timeout is specified.
|
return Reserve(Resource, Amount, KTimeManager.ConvertMillisecondsToNanoseconds(Time10SecondsMs));
|
||||||
return Reserve(Resource, Amount, KTimeManager.ConvertMillisecondsToNanoseconds(10000));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Reserve(LimitableResource Resource, long Amount, long Timeout)
|
public bool Reserve(LimitableResource Resource, long Amount, long Timeout)
|
||||||
|
@ -77,6 +83,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Release(LimitableResource Resource, ulong Amount)
|
||||||
|
{
|
||||||
|
Release(Resource, (long)Amount);
|
||||||
|
}
|
||||||
|
|
||||||
public void Release(LimitableResource Resource, long Amount)
|
public void Release(LimitableResource Resource, long Amount)
|
||||||
{
|
{
|
||||||
Release(Resource, Amount, Amount);
|
Release(Resource, Amount, Amount);
|
||||||
|
|
|
@ -25,12 +25,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
public KernelResult MapIntoProcess(
|
public KernelResult MapIntoProcess(
|
||||||
KMemoryManager MemoryManager,
|
KMemoryManager MemoryManager,
|
||||||
long Address,
|
ulong Address,
|
||||||
long Size,
|
ulong Size,
|
||||||
KProcess Process,
|
KProcess Process,
|
||||||
MemoryPermission Permission)
|
MemoryPermission Permission)
|
||||||
{
|
{
|
||||||
long PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
|
ulong PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
|
||||||
|
|
||||||
if (PageList.GetPagesCount() != PagesCountRounded)
|
if (PageList.GetPagesCount() != PagesCountRounded)
|
||||||
{
|
{
|
||||||
|
@ -51,11 +51,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
public KernelResult UnmapFromProcess(
|
public KernelResult UnmapFromProcess(
|
||||||
KMemoryManager MemoryManager,
|
KMemoryManager MemoryManager,
|
||||||
long Address,
|
ulong Address,
|
||||||
long Size,
|
ulong Size,
|
||||||
KProcess Process)
|
KProcess Process)
|
||||||
{
|
{
|
||||||
long PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
|
ulong PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
|
||||||
|
|
||||||
if (PageList.GetPagesCount() != PagesCountRounded)
|
if (PageList.GetPagesCount() != PagesCountRounded)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,11 +4,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
class KSlabHeap
|
class KSlabHeap
|
||||||
{
|
{
|
||||||
private LinkedList<long> Items;
|
private LinkedList<ulong> Items;
|
||||||
|
|
||||||
public KSlabHeap(long Pa, long ItemSize, long Size)
|
public KSlabHeap(ulong Pa, ulong ItemSize, ulong Size)
|
||||||
{
|
{
|
||||||
Items = new LinkedList<long>();
|
Items = new LinkedList<ulong>();
|
||||||
|
|
||||||
int ItemsCount = (int)(Size / ItemSize);
|
int ItemsCount = (int)(Size / ItemSize);
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetItem(out long Pa)
|
public bool TryGetItem(out ulong Pa)
|
||||||
{
|
{
|
||||||
lock (Items)
|
lock (Items)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Free(long Pa)
|
public void Free(ulong Pa)
|
||||||
{
|
{
|
||||||
lock (Items)
|
lock (Items)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,13 +22,13 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
public long CondVarAddress { get; set; }
|
public long CondVarAddress { get; set; }
|
||||||
|
|
||||||
private long Entrypoint;
|
private ulong Entrypoint;
|
||||||
|
|
||||||
public long MutexAddress { get; set; }
|
public long MutexAddress { get; set; }
|
||||||
|
|
||||||
public KProcess Owner { get; private set; }
|
public KProcess Owner { get; private set; }
|
||||||
|
|
||||||
private long TlsAddress;
|
private ulong TlsAddress;
|
||||||
|
|
||||||
public long LastScheduledTime { get; set; }
|
public long LastScheduledTime { get; set; }
|
||||||
|
|
||||||
|
@ -87,9 +87,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
public KernelResult Initialize(
|
public KernelResult Initialize(
|
||||||
long Entrypoint,
|
ulong Entrypoint,
|
||||||
long ArgsPtr,
|
ulong ArgsPtr,
|
||||||
long StackTop,
|
ulong StackTop,
|
||||||
int Priority,
|
int Priority,
|
||||||
int DefaultCpuCore,
|
int DefaultCpuCore,
|
||||||
KProcess Owner,
|
KProcess Owner,
|
||||||
|
@ -124,7 +124,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return KernelResult.OutOfMemory;
|
return KernelResult.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryHelper.FillWithZeros(Owner.CpuMemory, TlsAddress, KTlsPageInfo.TlsEntrySize);
|
MemoryHelper.FillWithZeros(Owner.CpuMemory, (long)TlsAddress, KTlsPageInfo.TlsEntrySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Is64Bits;
|
bool Is64Bits;
|
||||||
|
@ -142,13 +142,13 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
Is64Bits = true;
|
Is64Bits = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context = new CpuThread(Owner.Translator, Owner.CpuMemory, Entrypoint);
|
Context = new CpuThread(Owner.Translator, Owner.CpuMemory, (long)Entrypoint);
|
||||||
|
|
||||||
Context.ThreadState.X0 = (ulong)ArgsPtr;
|
Context.ThreadState.X0 = ArgsPtr;
|
||||||
Context.ThreadState.X31 = (ulong)StackTop;
|
Context.ThreadState.X31 = StackTop;
|
||||||
|
|
||||||
Context.ThreadState.CntfrqEl0 = 19200000;
|
Context.ThreadState.CntfrqEl0 = 19200000;
|
||||||
Context.ThreadState.Tpidr = TlsAddress;
|
Context.ThreadState.Tpidr = (long)TlsAddress;
|
||||||
|
|
||||||
Owner.SubscribeThreadEventHandlers(Context);
|
Owner.SubscribeThreadEventHandlers(Context);
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
public const int TlsEntrySize = 0x200;
|
public const int TlsEntrySize = 0x200;
|
||||||
|
|
||||||
public long PageAddr { get; private set; }
|
public ulong PageAddr { get; private set; }
|
||||||
|
|
||||||
private bool[] IsSlotFree;
|
private bool[] IsSlotFree;
|
||||||
|
|
||||||
public KTlsPageInfo(long PageAddress)
|
public KTlsPageInfo(ulong PageAddress)
|
||||||
{
|
{
|
||||||
this.PageAddr = PageAddress;
|
this.PageAddr = PageAddress;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetFreePage(out long Address)
|
public bool TryGetFreePage(out ulong Address)
|
||||||
{
|
{
|
||||||
Address = PageAddr;
|
Address = PageAddr;
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return AllFree;
|
return AllFree;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FreeTlsSlot(long Address)
|
public void FreeTlsSlot(ulong Address)
|
||||||
{
|
{
|
||||||
IsSlotFree[(Address - PageAddr) / TlsEntrySize] = true;
|
IsSlotFree[(Address - PageAddr) / TlsEntrySize] = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
class KTransferMemory
|
class KTransferMemory
|
||||||
{
|
{
|
||||||
public long Position { get; private set; }
|
public ulong Address { get; private set; }
|
||||||
public long Size { get; private set; }
|
public ulong Size { get; private set; }
|
||||||
|
|
||||||
public KTransferMemory(long Position, long Size)
|
public KTransferMemory(ulong Address, ulong Size)
|
||||||
{
|
{
|
||||||
this.Position = Position;
|
this.Address = Address;
|
||||||
this.Size = Size;
|
this.Size = Size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,23 +59,23 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
ulong RamSize = (ulong)GetRamSize(KernelMemoryCfg);
|
ulong RamSize = (ulong)GetRamSize(KernelMemoryCfg);
|
||||||
|
|
||||||
long RamPart0;
|
ulong RamPart0;
|
||||||
long RamPart1;
|
ulong RamPart1;
|
||||||
|
|
||||||
if (RamSize * 2 > EmemApertureSize)
|
if (RamSize * 2 > EmemApertureSize)
|
||||||
{
|
{
|
||||||
RamPart0 = (long)(EmemApertureSize / 2);
|
RamPart0 = EmemApertureSize / 2;
|
||||||
RamPart1 = (long)(EmemApertureSize / 2);
|
RamPart1 = EmemApertureSize / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RamPart0 = (long)EmemApertureSize;
|
RamPart0 = EmemApertureSize;
|
||||||
RamPart1 = 0;
|
RamPart1 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MemoryArrange = 1;
|
int MemoryArrange = 1;
|
||||||
|
|
||||||
long ApplicationRgSize;
|
ulong ApplicationRgSize;
|
||||||
|
|
||||||
switch (MemoryArrange)
|
switch (MemoryArrange)
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
default: ApplicationRgSize = 0xcd500000; break;
|
default: ApplicationRgSize = 0xcd500000; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
long AppletRgSize;
|
ulong AppletRgSize;
|
||||||
|
|
||||||
switch (MemoryArrange)
|
switch (MemoryArrange)
|
||||||
{
|
{
|
||||||
|
@ -102,13 +102,13 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
KMemoryArrangeRegion AppletRg;
|
KMemoryArrangeRegion AppletRg;
|
||||||
KMemoryArrangeRegion ApplicationRg;
|
KMemoryArrangeRegion ApplicationRg;
|
||||||
|
|
||||||
const long NvServicesRgSize = 0x29ba000;
|
const ulong NvServicesRgSize = 0x29ba000;
|
||||||
|
|
||||||
long ApplicationRgEnd = DramMemoryMap.DramEnd; //- RamPart0;
|
ulong ApplicationRgEnd = DramMemoryMap.DramEnd; //- RamPart0;
|
||||||
|
|
||||||
ApplicationRg = new KMemoryArrangeRegion(ApplicationRgEnd - ApplicationRgSize, ApplicationRgSize);
|
ApplicationRg = new KMemoryArrangeRegion(ApplicationRgEnd - ApplicationRgSize, ApplicationRgSize);
|
||||||
|
|
||||||
long NvServicesRgEnd = ApplicationRg.Address - AppletRgSize;
|
ulong NvServicesRgEnd = ApplicationRg.Address - AppletRgSize;
|
||||||
|
|
||||||
NvServicesRg = new KMemoryArrangeRegion(NvServicesRgEnd - NvServicesRgSize, NvServicesRgSize);
|
NvServicesRg = new KMemoryArrangeRegion(NvServicesRgEnd - NvServicesRgSize, NvServicesRgSize);
|
||||||
AppletRg = new KMemoryArrangeRegion(NvServicesRgEnd, AppletRgSize);
|
AppletRg = new KMemoryArrangeRegion(NvServicesRgEnd, AppletRgSize);
|
||||||
|
@ -116,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
//Note: There is an extra region used by the kernel, however
|
//Note: There is an extra region used by the kernel, however
|
||||||
//since we are doing HLE we are not going to use that memory, so give all
|
//since we are doing HLE we are not going to use that memory, so give all
|
||||||
//the remaining memory space to services.
|
//the remaining memory space to services.
|
||||||
long ServiceRgSize = NvServicesRg.Address - DramMemoryMap.SlabHeapEnd;
|
ulong ServiceRgSize = NvServicesRg.Address - DramMemoryMap.SlabHeapEnd;
|
||||||
|
|
||||||
ServiceRg = new KMemoryArrangeRegion(DramMemoryMap.SlabHeapEnd, ServiceRgSize);
|
ServiceRg = new KMemoryArrangeRegion(DramMemoryMap.SlabHeapEnd, ServiceRgSize);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
public int Category { get; private set; }
|
public int Category { get; private set; }
|
||||||
public long TitleId { get; private set; }
|
public long TitleId { get; private set; }
|
||||||
|
|
||||||
public long CodeAddress { get; private set; }
|
public ulong CodeAddress { get; private set; }
|
||||||
public int CodePagesCount { get; private set; }
|
public int CodePagesCount { get; private set; }
|
||||||
|
|
||||||
public int MmuFlags { get; private set; }
|
public int MmuFlags { get; private set; }
|
||||||
|
@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
string Name,
|
string Name,
|
||||||
int Category,
|
int Category,
|
||||||
long TitleId,
|
long TitleId,
|
||||||
long CodeAddress,
|
ulong CodeAddress,
|
||||||
int CodePagesCount,
|
int CodePagesCount,
|
||||||
int MmuFlags,
|
int MmuFlags,
|
||||||
int ResourceLimitHandle,
|
int ResourceLimitHandle,
|
||||||
|
|
|
@ -20,13 +20,13 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelResult Result = Process.MemoryManager.SetHeapSize((long)Size, out long Position);
|
KernelResult Result = Process.MemoryManager.SetHeapSize(Size, out ulong Position);
|
||||||
|
|
||||||
ThreadState.X0 = (ulong)Result;
|
ThreadState.X0 = (ulong)Result;
|
||||||
|
|
||||||
if (Result == KernelResult.Success)
|
if (Result == KernelResult.Success)
|
||||||
{
|
{
|
||||||
ThreadState.X1 = (ulong)Position;
|
ThreadState.X1 = Position;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -36,8 +36,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private void SvcSetMemoryAttribute(CpuThreadState ThreadState)
|
private void SvcSetMemoryAttribute(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long Position = (long)ThreadState.X0;
|
ulong Position = ThreadState.X0;
|
||||||
long Size = (long)ThreadState.X1;
|
ulong Size = ThreadState.X1;
|
||||||
|
|
||||||
if (!PageAligned(Position))
|
if (!PageAligned(Position))
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Memory.StopObservingRegion(Position, Size);
|
Memory.StopObservingRegion((long)Position, (long)Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadState.X0 = (ulong)Result;
|
ThreadState.X0 = (ulong)Result;
|
||||||
|
@ -92,9 +92,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private void SvcMapMemory(CpuThreadState ThreadState)
|
private void SvcMapMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long Dst = (long)ThreadState.X0;
|
ulong Dst = ThreadState.X0;
|
||||||
long Src = (long)ThreadState.X1;
|
ulong Src = ThreadState.X1;
|
||||||
long Size = (long)ThreadState.X2;
|
ulong Size = ThreadState.X2;
|
||||||
|
|
||||||
if (!PageAligned(Src | Dst))
|
if (!PageAligned(Src | Dst))
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)(Src + Size) <= (ulong)Src || (ulong)(Dst + Size) <= (ulong)Dst)
|
if (Src + Size <= Src || Dst + Size <= Dst)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
|
||||||
|
|
||||||
|
@ -123,7 +123,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideAddrSpace(Src, Size))
|
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||||
|
|
||||||
|
if (!CurrentProcess.MemoryManager.InsideAddrSpace(Src, Size))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
|
||||||
|
|
||||||
|
@ -132,7 +134,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideNewMapRegion(Dst, Size))
|
if (CurrentProcess.MemoryManager.OutsideStackRegion(Dst, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideHeapRegion (Dst, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideAliasRegion (Dst, Size))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
|
||||||
|
|
||||||
|
@ -153,9 +157,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private void SvcUnmapMemory(CpuThreadState ThreadState)
|
private void SvcUnmapMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long Dst = (long)ThreadState.X0;
|
ulong Dst = ThreadState.X0;
|
||||||
long Src = (long)ThreadState.X1;
|
ulong Src = ThreadState.X1;
|
||||||
long Size = (long)ThreadState.X2;
|
ulong Size = ThreadState.X2;
|
||||||
|
|
||||||
if (!PageAligned(Src | Dst))
|
if (!PageAligned(Src | Dst))
|
||||||
{
|
{
|
||||||
|
@ -175,7 +179,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)(Src + Size) <= (ulong)Src || (ulong)(Dst + Size) <= (ulong)Dst)
|
if (Src + Size <= Src || Dst + Size <= Dst)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
|
||||||
|
|
||||||
|
@ -184,7 +188,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideAddrSpace(Src, Size))
|
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||||
|
|
||||||
|
if (!CurrentProcess.MemoryManager.InsideAddrSpace(Src, Size))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
|
||||||
|
|
||||||
|
@ -193,7 +199,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideNewMapRegion(Dst, Size))
|
if (CurrentProcess.MemoryManager.OutsideStackRegion(Dst, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideHeapRegion (Dst, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideAliasRegion (Dst, Size))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
|
||||||
|
|
||||||
|
@ -215,12 +223,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
private void SvcQueryMemory(CpuThreadState ThreadState)
|
private void SvcQueryMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long InfoPtr = (long)ThreadState.X0;
|
long InfoPtr = (long)ThreadState.X0;
|
||||||
long Position = (long)ThreadState.X2;
|
ulong Position = ThreadState.X2;
|
||||||
|
|
||||||
KMemoryInfo BlkInfo = Process.MemoryManager.QueryMemory(Position);
|
KMemoryInfo BlkInfo = Process.MemoryManager.QueryMemory(Position);
|
||||||
|
|
||||||
Memory.WriteInt64(InfoPtr + 0x00, BlkInfo.Address);
|
Memory.WriteUInt64(InfoPtr + 0x00, BlkInfo.Address);
|
||||||
Memory.WriteInt64(InfoPtr + 0x08, BlkInfo.Size);
|
Memory.WriteUInt64(InfoPtr + 0x08, BlkInfo.Size);
|
||||||
Memory.WriteInt32 (InfoPtr + 0x10, (int)BlkInfo.State & 0xff);
|
Memory.WriteInt32 (InfoPtr + 0x10, (int)BlkInfo.State & 0xff);
|
||||||
Memory.WriteInt32 (InfoPtr + 0x14, (int)BlkInfo.Attribute);
|
Memory.WriteInt32 (InfoPtr + 0x14, (int)BlkInfo.Attribute);
|
||||||
Memory.WriteInt32 (InfoPtr + 0x18, (int)BlkInfo.Permission);
|
Memory.WriteInt32 (InfoPtr + 0x18, (int)BlkInfo.Permission);
|
||||||
|
@ -235,8 +243,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
private void SvcMapSharedMemory(CpuThreadState ThreadState)
|
private void SvcMapSharedMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
int Handle = (int)ThreadState.X0;
|
int Handle = (int)ThreadState.X0;
|
||||||
long Address = (long)ThreadState.X1;
|
ulong Address = ThreadState.X1;
|
||||||
long Size = (long)ThreadState.X2;
|
ulong Size = ThreadState.X2;
|
||||||
|
|
||||||
if (!PageAligned(Address))
|
if (!PageAligned(Address))
|
||||||
{
|
{
|
||||||
|
@ -289,7 +297,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideAddrSpace(Address, Size) || InsideMapRegion(Address, Size) || InsideHeapRegion(Address, Size))
|
if (CurrentProcess.MemoryManager.IsInvalidRegion (Address, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideHeapRegion (Address, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideAliasRegion(Address, Size))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!");
|
||||||
|
|
||||||
|
@ -316,12 +326,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
private void SvcUnmapSharedMemory(CpuThreadState ThreadState)
|
private void SvcUnmapSharedMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
int Handle = (int)ThreadState.X0;
|
int Handle = (int)ThreadState.X0;
|
||||||
long Position = (long)ThreadState.X1;
|
ulong Address = ThreadState.X1;
|
||||||
long Size = (long)ThreadState.X2;
|
ulong Size = ThreadState.X2;
|
||||||
|
|
||||||
if (!PageAligned(Position))
|
if (!PageAligned(Address))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||||
|
|
||||||
|
@ -337,9 +347,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
if ((ulong)(Address + Size) <= (ulong)Address)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||||
|
|
||||||
|
@ -359,9 +369,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideAddrSpace(Position, Size) || InsideMapRegion(Position, Size) || InsideHeapRegion(Position, Size))
|
if (CurrentProcess.MemoryManager.IsInvalidRegion (Address, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideHeapRegion (Address, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.InsideAliasRegion(Address, Size))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} out of range!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||||
|
|
||||||
|
@ -370,7 +382,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
KernelResult Result = SharedMemory.UnmapFromProcess(
|
KernelResult Result = SharedMemory.UnmapFromProcess(
|
||||||
CurrentProcess.MemoryManager,
|
CurrentProcess.MemoryManager,
|
||||||
Position,
|
Address,
|
||||||
Size,
|
Size,
|
||||||
CurrentProcess);
|
CurrentProcess);
|
||||||
|
|
||||||
|
@ -384,12 +396,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private void SvcCreateTransferMemory(CpuThreadState ThreadState)
|
private void SvcCreateTransferMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long Position = (long)ThreadState.X1;
|
ulong Address = ThreadState.X1;
|
||||||
long Size = (long)ThreadState.X2;
|
ulong Size = ThreadState.X2;
|
||||||
|
|
||||||
if (!PageAligned(Position))
|
if (!PageAligned(Address))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||||
|
|
||||||
|
@ -405,9 +417,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
if ((ulong)(Address + Size) <= (ulong)Address)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||||
|
|
||||||
|
@ -425,9 +437,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process.MemoryManager.ReserveTransferMemory(Position, Size, Permission);
|
Process.MemoryManager.ReserveTransferMemory(Address, Size, Permission);
|
||||||
|
|
||||||
KTransferMemory TransferMemory = new KTransferMemory(Position, Size);
|
KTransferMemory TransferMemory = new KTransferMemory(Address, Size);
|
||||||
|
|
||||||
KernelResult Result = Process.HandleTable.GenerateHandle(TransferMemory, out int Handle);
|
KernelResult Result = Process.HandleTable.GenerateHandle(TransferMemory, out int Handle);
|
||||||
|
|
||||||
|
@ -437,12 +449,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private void SvcMapPhysicalMemory(CpuThreadState ThreadState)
|
private void SvcMapPhysicalMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long Position = (long)ThreadState.X0;
|
ulong Address = ThreadState.X0;
|
||||||
long Size = (long)ThreadState.X1;
|
ulong Size = ThreadState.X1;
|
||||||
|
|
||||||
if (!PageAligned(Position))
|
if (!PageAligned(Address))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||||
|
|
||||||
|
@ -458,25 +470,37 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
if (Address + Size <= Address)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideAddrSpace(Position, Size))
|
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||||
|
|
||||||
|
if ((CurrentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Position:x16}!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
|
||||||
|
|
||||||
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CurrentProcess.MemoryManager.InsideAddrSpace (Address, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.OutsideAliasRegion(Address, Size))
|
||||||
|
{
|
||||||
|
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Address:x16}.");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelResult Result = Process.MemoryManager.MapPhysicalMemory(Position, Size);
|
KernelResult Result = Process.MemoryManager.MapPhysicalMemory(Address, Size);
|
||||||
|
|
||||||
if (Result != KernelResult.Success)
|
if (Result != KernelResult.Success)
|
||||||
{
|
{
|
||||||
|
@ -488,12 +512,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
private void SvcUnmapPhysicalMemory(CpuThreadState ThreadState)
|
private void SvcUnmapPhysicalMemory(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long Position = (long)ThreadState.X0;
|
ulong Address = ThreadState.X0;
|
||||||
long Size = (long)ThreadState.X1;
|
ulong Size = ThreadState.X1;
|
||||||
|
|
||||||
if (!PageAligned(Position))
|
if (!PageAligned(Address))
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||||
|
|
||||||
|
@ -509,25 +533,37 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
if ((ulong)(Address + Size) <= (ulong)Address)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InsideAddrSpace(Position, Size))
|
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||||
|
|
||||||
|
if ((CurrentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
|
||||||
{
|
{
|
||||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Position:x16}!");
|
Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
|
||||||
|
|
||||||
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CurrentProcess.MemoryManager.InsideAddrSpace (Address, Size) ||
|
||||||
|
CurrentProcess.MemoryManager.OutsideAliasRegion(Address, Size))
|
||||||
|
{
|
||||||
|
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Address:x16}.");
|
||||||
|
|
||||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelResult Result = Process.MemoryManager.UnmapPhysicalMemory(Position, Size);
|
KernelResult Result = Process.MemoryManager.UnmapPhysicalMemory(Address, Size);
|
||||||
|
|
||||||
if (Result != KernelResult.Success)
|
if (Result != KernelResult.Success)
|
||||||
{
|
{
|
||||||
|
@ -537,45 +573,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
ThreadState.X0 = (ulong)Result;
|
ThreadState.X0 = (ulong)Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool PageAligned(long Position)
|
private static bool PageAligned(ulong Position)
|
||||||
{
|
{
|
||||||
return (Position & (KMemoryManager.PageSize - 1)) == 0;
|
return (Position & (KMemoryManager.PageSize - 1)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool InsideAddrSpace(long Position, long Size)
|
|
||||||
{
|
|
||||||
ulong Start = (ulong)Position;
|
|
||||||
ulong End = (ulong)Size + Start;
|
|
||||||
|
|
||||||
return Start >= (ulong)Process.MemoryManager.AddrSpaceStart &&
|
|
||||||
End < (ulong)Process.MemoryManager.AddrSpaceEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool InsideMapRegion(long Position, long Size)
|
|
||||||
{
|
|
||||||
ulong Start = (ulong)Position;
|
|
||||||
ulong End = (ulong)Size + Start;
|
|
||||||
|
|
||||||
return Start >= (ulong)Process.MemoryManager.AliasRegionStart &&
|
|
||||||
End < (ulong)Process.MemoryManager.AliasRegionEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool InsideHeapRegion(long Position, long Size)
|
|
||||||
{
|
|
||||||
ulong Start = (ulong)Position;
|
|
||||||
ulong End = (ulong)Size + Start;
|
|
||||||
|
|
||||||
return Start >= (ulong)Process.MemoryManager.HeapRegionStart &&
|
|
||||||
End < (ulong)Process.MemoryManager.HeapRegionEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool InsideNewMapRegion(long Position, long Size)
|
|
||||||
{
|
|
||||||
ulong Start = (ulong)Position;
|
|
||||||
ulong End = (ulong)Size + Start;
|
|
||||||
|
|
||||||
return Start >= (ulong)Process.MemoryManager.StackRegionStart &&
|
|
||||||
End < (ulong)Process.MemoryManager.StackRegionEnd;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -107,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
else if (Obj is KTransferMemory TransferMemory)
|
else if (Obj is KTransferMemory TransferMemory)
|
||||||
{
|
{
|
||||||
Process.MemoryManager.ResetTransferMemory(
|
Process.MemoryManager.ResetTransferMemory(
|
||||||
TransferMemory.Position,
|
TransferMemory.Address,
|
||||||
TransferMemory.Size);
|
TransferMemory.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,27 +339,27 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
case 0: Value = Process.Capabilities.AllowedCpuCoresMask; break;
|
case 0: Value = Process.Capabilities.AllowedCpuCoresMask; break;
|
||||||
case 1: Value = Process.Capabilities.AllowedThreadPriosMask; break;
|
case 1: Value = Process.Capabilities.AllowedThreadPriosMask; break;
|
||||||
|
|
||||||
case 2: Value = Process.MemoryManager.AliasRegionStart; break;
|
case 2: Value = (long)Process.MemoryManager.AliasRegionStart; break;
|
||||||
case 3: Value = Process.MemoryManager.AliasRegionEnd -
|
case 3: Value = (long)(Process.MemoryManager.AliasRegionEnd -
|
||||||
Process.MemoryManager.AliasRegionStart; break;
|
Process.MemoryManager.AliasRegionStart); break;
|
||||||
|
|
||||||
case 4: Value = Process.MemoryManager.HeapRegionStart; break;
|
case 4: Value = (long)Process.MemoryManager.HeapRegionStart; break;
|
||||||
case 5: Value = Process.MemoryManager.HeapRegionEnd -
|
case 5: Value = (long)(Process.MemoryManager.HeapRegionEnd -
|
||||||
Process.MemoryManager.HeapRegionStart; break;
|
Process.MemoryManager.HeapRegionStart); break;
|
||||||
|
|
||||||
case 6: Value = Process.GetMemoryCapacity(); break;
|
case 6: Value = (long)Process.GetMemoryCapacity(); break;
|
||||||
|
|
||||||
case 7: Value = Process.GetMemoryUsage(); break;
|
case 7: Value = (long)Process.GetMemoryUsage(); break;
|
||||||
|
|
||||||
case 12: Value = Process.MemoryManager.GetAddrSpaceBaseAddr(); break;
|
case 12: Value = (long)Process.MemoryManager.GetAddrSpaceBaseAddr(); break;
|
||||||
|
|
||||||
case 13: Value = Process.MemoryManager.GetAddrSpaceSize(); break;
|
case 13: Value = (long)Process.MemoryManager.GetAddrSpaceSize(); break;
|
||||||
|
|
||||||
case 14: Value = Process.MemoryManager.StackRegionStart; break;
|
case 14: Value = (long)Process.MemoryManager.StackRegionStart; break;
|
||||||
case 15: Value = Process.MemoryManager.StackRegionEnd -
|
case 15: Value = (long)(Process.MemoryManager.StackRegionEnd -
|
||||||
Process.MemoryManager.StackRegionStart; break;
|
Process.MemoryManager.StackRegionStart); break;
|
||||||
|
|
||||||
case 16: Value = Process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;
|
case 16: Value = (long)Process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;
|
||||||
|
|
||||||
case 17:
|
case 17:
|
||||||
if (Process.PersonalMmHeapPagesCount != 0)
|
if (Process.PersonalMmHeapPagesCount != 0)
|
||||||
|
@ -371,11 +371,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
case 18: Value = Process.TitleId; break;
|
case 18: Value = Process.TitleId; break;
|
||||||
|
|
||||||
case 20: Value = Process.UserExceptionContextAddress; break;
|
case 20: Value = (long)Process.UserExceptionContextAddress; break;
|
||||||
|
|
||||||
case 21: Value = Process.GetMemoryCapacityWithoutPersonalMmHeap(); break;
|
case 21: Value = (long)Process.GetMemoryCapacityWithoutPersonalMmHeap(); break;
|
||||||
|
|
||||||
case 22: Value = Process.GetMemoryUsageWithoutPersonalMmHeap(); break;
|
case 22: Value = (long)Process.GetMemoryUsageWithoutPersonalMmHeap(); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
{
|
{
|
||||||
private void CreateThread64(CpuThreadState ThreadState)
|
private void CreateThread64(CpuThreadState ThreadState)
|
||||||
{
|
{
|
||||||
long Entrypoint = (long)ThreadState.X1;
|
ulong Entrypoint = ThreadState.X1;
|
||||||
long ArgsPtr = (long)ThreadState.X2;
|
ulong ArgsPtr = ThreadState.X2;
|
||||||
long StackTop = (long)ThreadState.X3;
|
ulong StackTop = ThreadState.X3;
|
||||||
int Priority = (int)ThreadState.X4;
|
int Priority = (int)ThreadState.X4;
|
||||||
int CpuCore = (int)ThreadState.X5;
|
int CpuCore = (int)ThreadState.X5;
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
private KernelResult CreateThread(
|
private KernelResult CreateThread(
|
||||||
long Entrypoint,
|
ulong Entrypoint,
|
||||||
long ArgsPtr,
|
ulong ArgsPtr,
|
||||||
long StackTop,
|
ulong StackTop,
|
||||||
int Priority,
|
int Priority,
|
||||||
int CpuCore,
|
int CpuCore,
|
||||||
out int Handle)
|
out int Handle)
|
||||||
|
|
|
@ -19,12 +19,12 @@ namespace Ryujinx.HLE.HOS
|
||||||
IExecutable[] StaticObjects,
|
IExecutable[] StaticObjects,
|
||||||
byte[] Arguments = null)
|
byte[] Arguments = null)
|
||||||
{
|
{
|
||||||
long ArgsStart = 0;
|
ulong ArgsStart = 0;
|
||||||
int ArgsSize = 0;
|
int ArgsSize = 0;
|
||||||
long CodeStart = 0x8000000;
|
ulong CodeStart = 0x8000000;
|
||||||
int CodeSize = 0;
|
int CodeSize = 0;
|
||||||
|
|
||||||
long[] NsoBase = new long[StaticObjects.Length];
|
ulong[] NsoBase = new ulong[StaticObjects.Length];
|
||||||
|
|
||||||
for (int Index = 0; Index < StaticObjects.Length; Index++)
|
for (int Index = 0; Index < StaticObjects.Length; Index++)
|
||||||
{
|
{
|
||||||
|
@ -48,13 +48,13 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
NsoSize = BitUtils.AlignUp(NsoSize, KMemoryManager.PageSize);
|
NsoSize = BitUtils.AlignUp(NsoSize, KMemoryManager.PageSize);
|
||||||
|
|
||||||
NsoBase[Index] = CodeStart + CodeSize;
|
NsoBase[Index] = CodeStart + (ulong)CodeSize;
|
||||||
|
|
||||||
CodeSize += NsoSize;
|
CodeSize += NsoSize;
|
||||||
|
|
||||||
if (Arguments != null && ArgsSize == 0)
|
if (Arguments != null && ArgsSize == 0)
|
||||||
{
|
{
|
||||||
ArgsStart = CodeSize;
|
ArgsStart = (ulong)CodeSize;
|
||||||
|
|
||||||
ArgsSize = BitUtils.AlignDown(Arguments.Length * 2 + ArgsTotalSize - 1, KMemoryManager.PageSize);
|
ArgsSize = BitUtils.AlignDown(Arguments.Length * 2 + ArgsTotalSize - 1, KMemoryManager.PageSize);
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
KResourceLimit ResourceLimit = new KResourceLimit(System);
|
KResourceLimit ResourceLimit = new KResourceLimit(System);
|
||||||
|
|
||||||
long ApplicationRgSize = System.MemoryRegions[(int)MemoryRegion.Application].Size;
|
long ApplicationRgSize = (long)System.MemoryRegions[(int)MemoryRegion.Application].Size;
|
||||||
|
|
||||||
Result = ResourceLimit.SetLimitValue(LimitableResource.Memory, ApplicationRgSize);
|
Result = ResourceLimit.SetLimitValue(LimitableResource.Memory, ApplicationRgSize);
|
||||||
Result |= ResourceLimit.SetLimitValue(LimitableResource.Thread, 608);
|
Result |= ResourceLimit.SetLimitValue(LimitableResource.Thread, 608);
|
||||||
|
@ -114,26 +114,26 @@ namespace Ryujinx.HLE.HOS
|
||||||
{
|
{
|
||||||
IExecutable StaticObject = StaticObjects[Index];
|
IExecutable StaticObject = StaticObjects[Index];
|
||||||
|
|
||||||
long TextStart = NsoBase[Index] + StaticObject.TextOffset;
|
ulong TextStart = NsoBase[Index] + (ulong)StaticObject.TextOffset;
|
||||||
long ROStart = NsoBase[Index] + StaticObject.ROOffset;
|
ulong ROStart = NsoBase[Index] + (ulong)StaticObject.ROOffset;
|
||||||
long DataStart = NsoBase[Index] + StaticObject.DataOffset;
|
ulong DataStart = NsoBase[Index] + (ulong)StaticObject.DataOffset;
|
||||||
|
|
||||||
long BssStart = DataStart + StaticObject.Data.Length;
|
ulong BssStart = DataStart + (ulong)StaticObject.Data.Length;
|
||||||
|
|
||||||
long BssEnd = BitUtils.AlignUp(BssStart + StaticObject.BssSize, KMemoryManager.PageSize);
|
ulong BssEnd = BitUtils.AlignUp(BssStart + (ulong)StaticObject.BssSize, KMemoryManager.PageSize);
|
||||||
|
|
||||||
Process.CpuMemory.WriteBytes(TextStart, StaticObject.Text);
|
Process.CpuMemory.WriteBytes((long)TextStart, StaticObject.Text);
|
||||||
Process.CpuMemory.WriteBytes(ROStart, StaticObject.RO);
|
Process.CpuMemory.WriteBytes((long)ROStart, StaticObject.RO);
|
||||||
Process.CpuMemory.WriteBytes(DataStart, StaticObject.Data);
|
Process.CpuMemory.WriteBytes((long)DataStart, StaticObject.Data);
|
||||||
|
|
||||||
MemoryHelper.FillWithZeros(Process.CpuMemory, BssStart, (int)(BssEnd - BssStart));
|
MemoryHelper.FillWithZeros(Process.CpuMemory, (long)BssStart, (int)(BssEnd - BssStart));
|
||||||
|
|
||||||
Process.MemoryManager.SetProcessMemoryPermission(TextStart, ROStart - TextStart, MemoryPermission.ReadAndExecute);
|
Process.MemoryManager.SetProcessMemoryPermission(TextStart, ROStart - TextStart, MemoryPermission.ReadAndExecute);
|
||||||
Process.MemoryManager.SetProcessMemoryPermission(ROStart, DataStart - ROStart, MemoryPermission.Read);
|
Process.MemoryManager.SetProcessMemoryPermission(ROStart, DataStart - ROStart, MemoryPermission.Read);
|
||||||
Process.MemoryManager.SetProcessMemoryPermission(DataStart, BssEnd - DataStart, MemoryPermission.ReadAndWrite);
|
Process.MemoryManager.SetProcessMemoryPermission(DataStart, BssEnd - DataStart, MemoryPermission.ReadAndWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = Process.Start(MetaData.MainThreadPriority, MetaData.MainThreadStackSize);
|
Result = Process.Start(MetaData.MainThreadPriority, (ulong)MetaData.MainThreadStackSize);
|
||||||
|
|
||||||
if (Result != KernelResult.Success)
|
if (Result != KernelResult.Success)
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,11 +65,11 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
{
|
{
|
||||||
public NxRelocatableObject Executable { get; private set; }
|
public NxRelocatableObject Executable { get; private set; }
|
||||||
public byte[] Hash { get; private set; }
|
public byte[] Hash { get; private set; }
|
||||||
public long NroAddress { get; private set; }
|
public ulong NroAddress { get; private set; }
|
||||||
public long TotalSize { get; private set; }
|
public ulong TotalSize { get; private set; }
|
||||||
public long NroMappedAddress { get; set; }
|
public ulong NroMappedAddress { get; set; }
|
||||||
|
|
||||||
public NroInfo(NxRelocatableObject Executable, byte[] Hash, long TotalSize)
|
public NroInfo(NxRelocatableObject Executable, byte[] Hash, ulong TotalSize)
|
||||||
{
|
{
|
||||||
this.Executable = Executable;
|
this.Executable = Executable;
|
||||||
this.Hash = Hash;
|
this.Hash = Hash;
|
||||||
|
@ -175,7 +175,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long ParseNro(out NroInfo Res, ServiceCtx Context, long NroHeapAddress, long NroSize, long BssHeapAddress, long BssSize)
|
public long ParseNro(out NroInfo Res, ServiceCtx Context, ulong NroHeapAddress, ulong NroSize, ulong BssHeapAddress, ulong BssSize)
|
||||||
{
|
{
|
||||||
Res = null;
|
Res = null;
|
||||||
|
|
||||||
|
@ -196,15 +196,15 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
return MakeError(ErrorModule.Loader, LoaderErr.UnalignedAddress);
|
return MakeError(ErrorModule.Loader, LoaderErr.UnalignedAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Magic = Context.Memory.ReadUInt32(NroHeapAddress + 0x10);
|
uint Magic = Context.Memory.ReadUInt32((long)NroHeapAddress + 0x10);
|
||||||
uint NroFileSize = Context.Memory.ReadUInt32(NroHeapAddress + 0x18);
|
uint NroFileSize = Context.Memory.ReadUInt32((long)NroHeapAddress + 0x18);
|
||||||
|
|
||||||
if (Magic != NroMagic || NroSize != NroFileSize)
|
if (Magic != NroMagic || NroSize != NroFileSize)
|
||||||
{
|
{
|
||||||
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
|
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] NroData = Context.Memory.ReadBytes(NroHeapAddress, NroSize);
|
byte[] NroData = Context.Memory.ReadBytes((long)NroHeapAddress, (long)NroSize);
|
||||||
byte[] NroHash = null;
|
byte[] NroHash = null;
|
||||||
|
|
||||||
MemoryStream Stream = new MemoryStream(NroData);
|
MemoryStream Stream = new MemoryStream(NroData);
|
||||||
|
@ -244,26 +244,29 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally check the bss size match.
|
// finally check the bss size match.
|
||||||
if (Executable.BssSize != BssSize)
|
if ((ulong)Executable.BssSize != BssSize)
|
||||||
{
|
{
|
||||||
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
|
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
|
||||||
}
|
}
|
||||||
|
|
||||||
Res = new NroInfo(Executable, NroHash, Executable.Text.Length + Executable.RO.Length + Executable.Data.Length + Executable.BssSize);
|
int TotalSize = Executable.Text.Length + Executable.RO.Length + Executable.Data.Length + Executable.BssSize;
|
||||||
|
|
||||||
|
Res = new NroInfo(Executable, NroHash, (ulong)TotalSize);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long MapNro(ServiceCtx Context, NroInfo Info, out long NroMappedAddress)
|
private long MapNro(ServiceCtx Context, NroInfo Info, out ulong NroMappedAddress)
|
||||||
{
|
{
|
||||||
NroMappedAddress = 0;
|
NroMappedAddress = 0;
|
||||||
long TargetAddress = Context.Process.MemoryManager.AddrSpaceStart;
|
|
||||||
|
|
||||||
long HeapRegionStart = Context.Process.MemoryManager.HeapRegionStart;
|
ulong TargetAddress = Context.Process.MemoryManager.AddrSpaceStart;
|
||||||
long HeapRegionEnd = Context.Process.MemoryManager.HeapRegionEnd;
|
|
||||||
|
|
||||||
long MapRegionStart = Context.Process.MemoryManager.AliasRegionStart;
|
ulong HeapRegionStart = Context.Process.MemoryManager.HeapRegionStart;
|
||||||
long MapRegionEnd = Context.Process.MemoryManager.AliasRegionEnd;
|
ulong HeapRegionEnd = Context.Process.MemoryManager.HeapRegionEnd;
|
||||||
|
|
||||||
|
ulong MapRegionStart = Context.Process.MemoryManager.AliasRegionStart;
|
||||||
|
ulong MapRegionEnd = Context.Process.MemoryManager.AliasRegionEnd;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -309,7 +312,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
return MakeError(ErrorModule.Loader, LoaderErr.BadNrrAddress);
|
return MakeError(ErrorModule.Loader, LoaderErr.BadNrrAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long RemoveNroInfo(ServiceCtx Context, long NroMappedAddress, long NroHeapAddress)
|
private long RemoveNroInfo(ServiceCtx Context, ulong NroMappedAddress, ulong NroHeapAddress)
|
||||||
{
|
{
|
||||||
foreach (NroInfo Info in NroInfos)
|
foreach (NroInfo Info in NroInfos)
|
||||||
{
|
{
|
||||||
|
@ -319,11 +322,17 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
|
|
||||||
//Context.Process.RemoveProgram(Info.NroMappedAddress);
|
//Context.Process.RemoveProgram(Info.NroMappedAddress);
|
||||||
|
|
||||||
KernelResult Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(Info.NroMappedAddress, Info.Executable.SourceAddress, Info.TotalSize - Info.Executable.BssSize);
|
KernelResult Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(
|
||||||
|
Info.NroMappedAddress,
|
||||||
|
Info.Executable.SourceAddress,
|
||||||
|
Info.TotalSize - (ulong)Info.Executable.BssSize);
|
||||||
|
|
||||||
if (Result == KernelResult.Success && Info.Executable.BssSize != 0)
|
if (Result == KernelResult.Success && Info.Executable.BssSize != 0)
|
||||||
{
|
{
|
||||||
Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(Info.NroMappedAddress + Info.TotalSize - Info.Executable.BssSize, Info.Executable.BssAddress, Info.Executable.BssSize);
|
Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(
|
||||||
|
Info.NroMappedAddress + Info.TotalSize - (ulong)Info.Executable.BssSize,
|
||||||
|
Info.Executable.BssAddress,
|
||||||
|
(ulong)Info.Executable.BssSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (long)Result;
|
return (long)Result;
|
||||||
|
@ -341,12 +350,12 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
// Zero
|
// Zero
|
||||||
Context.RequestData.ReadUInt64();
|
Context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
long NroHeapAddress = Context.RequestData.ReadInt64();
|
ulong NroHeapAddress = Context.RequestData.ReadUInt64();
|
||||||
long NroSize = Context.RequestData.ReadInt64();
|
ulong NroSize = Context.RequestData.ReadUInt64();
|
||||||
long BssHeapAddress = Context.RequestData.ReadInt64();
|
ulong BssHeapAddress = Context.RequestData.ReadUInt64();
|
||||||
long BssSize = Context.RequestData.ReadInt64();
|
ulong BssSize = Context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
long NroMappedAddress = 0;
|
ulong NroMappedAddress = 0;
|
||||||
|
|
||||||
if (IsInitialized)
|
if (IsInitialized)
|
||||||
{
|
{
|
||||||
|
@ -375,8 +384,8 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
|
||||||
{
|
{
|
||||||
long Result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
|
long Result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
|
||||||
|
|
||||||
long NroMappedAddress = Context.RequestData.ReadInt64();
|
ulong NroMappedAddress = Context.RequestData.ReadUInt64();
|
||||||
long NroHeapAddress = Context.RequestData.ReadInt64();
|
ulong NroHeapAddress = Context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
if (IsInitialized)
|
if (IsInitialized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,10 +14,10 @@ namespace Ryujinx.HLE.Loaders.Executables
|
||||||
public int DataOffset { get; private set; }
|
public int DataOffset { get; private set; }
|
||||||
public int BssSize { get; private set; }
|
public int BssSize { get; private set; }
|
||||||
|
|
||||||
public long SourceAddress { get; private set; }
|
public ulong SourceAddress { get; private set; }
|
||||||
public long BssAddress { get; private set; }
|
public ulong BssAddress { get; private set; }
|
||||||
|
|
||||||
public NxRelocatableObject(Stream Input, long SourceAddress = 0, long BssAddress = 0)
|
public NxRelocatableObject(Stream Input, ulong SourceAddress = 0, ulong BssAddress = 0)
|
||||||
{
|
{
|
||||||
this.SourceAddress = SourceAddress;
|
this.SourceAddress = SourceAddress;
|
||||||
this.BssAddress = BssAddress;
|
this.BssAddress = BssAddress;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue