93c083aef1
While èis generally representable in some language encodings, in some it isn't and will result in compilation warnings occurring. To remain friendly with other language's codepages on Windows, we normalize it to an ASCII e.
118 lines
5 KiB
C++
118 lines
5 KiB
C++
// Copyright 2020 yuzu Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
// This file references various implementation details from Atmosphere, an open-source firmware for
|
|
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
|
|
|
#include <array>
|
|
|
|
#include "common/assert.h"
|
|
#include "core/hle/kernel/memory/address_space_info.h"
|
|
|
|
namespace Kernel::Memory {
|
|
|
|
namespace {
|
|
|
|
enum : u64 {
|
|
Size_1_MB = 0x100000,
|
|
Size_2_MB = 2 * Size_1_MB,
|
|
Size_128_MB = 128 * Size_1_MB,
|
|
Size_1_GB = 0x40000000,
|
|
Size_2_GB = 2 * Size_1_GB,
|
|
Size_4_GB = 4 * Size_1_GB,
|
|
Size_6_GB = 6 * Size_1_GB,
|
|
Size_64_GB = 64 * Size_1_GB,
|
|
Size_512_GB = 512 * Size_1_GB,
|
|
Invalid = std::numeric_limits<u64>::max(),
|
|
};
|
|
|
|
// clang-format off
|
|
constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{
|
|
{ 32 /*bit_width*/, Size_2_MB /*addr*/, Size_1_GB - Size_2_MB /*size*/, AddressSpaceInfo::Type::Is32Bit, },
|
|
{ 32 /*bit_width*/, Size_1_GB /*addr*/, Size_4_GB - Size_1_GB /*size*/, AddressSpaceInfo::Type::Small64Bit, },
|
|
{ 32 /*bit_width*/, Invalid /*addr*/, Size_1_GB /*size*/, AddressSpaceInfo::Type::Heap, },
|
|
{ 32 /*bit_width*/, Invalid /*addr*/, Size_1_GB /*size*/, AddressSpaceInfo::Type::Alias, },
|
|
{ 36 /*bit_width*/, Size_128_MB /*addr*/, Size_2_GB - Size_128_MB /*size*/, AddressSpaceInfo::Type::Is32Bit, },
|
|
{ 36 /*bit_width*/, Size_2_GB /*addr*/, Size_64_GB - Size_2_GB /*size*/, AddressSpaceInfo::Type::Small64Bit, },
|
|
{ 36 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Heap, },
|
|
{ 36 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Alias, },
|
|
{ 39 /*bit_width*/, Size_128_MB /*addr*/, Size_512_GB - Size_128_MB /*size*/, AddressSpaceInfo::Type::Large64Bit, },
|
|
{ 39 /*bit_width*/, Invalid /*addr*/, Size_64_GB /*size*/, AddressSpaceInfo::Type::Is32Bit },
|
|
{ 39 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Heap, },
|
|
{ 39 /*bit_width*/, Invalid /*addr*/, Size_64_GB /*size*/, AddressSpaceInfo::Type::Alias, },
|
|
{ 39 /*bit_width*/, Invalid /*addr*/, Size_2_GB /*size*/, AddressSpaceInfo::Type::Stack, },
|
|
}};
|
|
// clang-format on
|
|
|
|
constexpr bool IsAllowedIndexForAddress(std::size_t index) {
|
|
return index < std::size(AddressSpaceInfos) && AddressSpaceInfos[index].GetAddress() != Invalid;
|
|
}
|
|
|
|
constexpr std::size_t
|
|
AddressSpaceIndices32Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
|
|
0, 1, 0, 2, 0, 3,
|
|
};
|
|
|
|
constexpr std::size_t
|
|
AddressSpaceIndices36Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
|
|
4, 5, 4, 6, 4, 7,
|
|
};
|
|
|
|
constexpr std::size_t
|
|
AddressSpaceIndices39Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
|
|
9, 8, 8, 10, 12, 11,
|
|
};
|
|
|
|
constexpr bool IsAllowed32BitType(AddressSpaceInfo::Type type) {
|
|
return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit &&
|
|
type != AddressSpaceInfo::Type::Stack;
|
|
}
|
|
|
|
constexpr bool IsAllowed36BitType(AddressSpaceInfo::Type type) {
|
|
return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit &&
|
|
type != AddressSpaceInfo::Type::Stack;
|
|
}
|
|
|
|
constexpr bool IsAllowed39BitType(AddressSpaceInfo::Type type) {
|
|
return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Small64Bit;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
u64 AddressSpaceInfo::GetAddressSpaceStart(std::size_t width, AddressSpaceInfo::Type type) {
|
|
const std::size_t index{static_cast<std::size_t>(type)};
|
|
switch (width) {
|
|
case 32:
|
|
ASSERT(IsAllowed32BitType(type));
|
|
ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices32Bit[index]));
|
|
return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].GetAddress();
|
|
case 36:
|
|
ASSERT(IsAllowed36BitType(type));
|
|
ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices36Bit[index]));
|
|
return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].GetAddress();
|
|
case 39:
|
|
ASSERT(IsAllowed39BitType(type));
|
|
ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index]));
|
|
return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].GetAddress();
|
|
}
|
|
UNREACHABLE();
|
|
}
|
|
|
|
std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, AddressSpaceInfo::Type type) {
|
|
const std::size_t index{static_cast<std::size_t>(type)};
|
|
switch (width) {
|
|
case 32:
|
|
ASSERT(IsAllowed32BitType(type));
|
|
return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].GetSize();
|
|
case 36:
|
|
ASSERT(IsAllowed36BitType(type));
|
|
return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].GetSize();
|
|
case 39:
|
|
ASSERT(IsAllowed39BitType(type));
|
|
return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].GetSize();
|
|
}
|
|
UNREACHABLE();
|
|
}
|
|
|
|
} // namespace Kernel::Memory
|