Change long -> ulong for address/size on memory related methods to avoid unnecessary casts

This commit is contained in:
gdkchan 2018-11-20 15:34:20 -03:00
commit 70e42d43d3
27 changed files with 683 additions and 655 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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;
} }
} }

View file

@ -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;

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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;
} }

View file

@ -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);

View file

@ -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)
{ {

View file

@ -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;

View file

@ -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)
{ {

View file

@ -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);

View file

@ -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)
{ {

View file

@ -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)
{ {

View file

@ -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);

View file

@ -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;
} }

View file

@ -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;
} }
} }

View file

@ -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);

View file

@ -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,

View file

@ -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;
}
} }
} }

View file

@ -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;

View file

@ -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)

View file

@ -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)
{ {

View file

@ -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)
{ {

View file

@ -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;