Browse Source
kernel: memory: Add AddressSpaceInfo class, for managing the memory address space.
pull/15/merge
kernel: memory: Add AddressSpaceInfo class, for managing the memory address space.
pull/15/merge
3 changed files with 166 additions and 0 deletions
-
2src/core/CMakeLists.txt
-
113src/core/hle/kernel/memory/address_space_info.cpp
-
51src/core/hle/kernel/memory/address_space_info.h
@ -0,0 +1,113 @@ |
|||
// Copyright 2020 yuzu Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <array>
|
|||
|
|||
#include "common/assert.h"
|
|||
#include "core/hle/kernel/memory/address_space_info.h"
|
|||
|
|||
namespace Kernel::Memory { |
|||
|
|||
namespace { |
|||
|
|||
constexpr std::size_t Size_1_MB{0x100000}; |
|||
constexpr std::size_t Size_2_MB{2 * Size_1_MB}; |
|||
constexpr std::size_t Size_128_MB{128 * Size_1_MB}; |
|||
constexpr std::size_t Size_1_GB{0x40000000}; |
|||
constexpr std::size_t Size_2_GB{2 * Size_1_GB}; |
|||
constexpr std::size_t Size_4_GB{4 * Size_1_GB}; |
|||
constexpr std::size_t Size_6_GB{6 * Size_1_GB}; |
|||
constexpr std::size_t Size_64_GB{64 * Size_1_GB}; |
|||
constexpr std::size_t Size_512_GB{512 * Size_1_GB}; |
|||
constexpr u64 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
|
|||
@ -0,0 +1,51 @@ |
|||
// Copyright 2020 yuzu Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
|
|||
namespace Kernel::Memory { |
|||
|
|||
class AddressSpaceInfo final : NonCopyable { |
|||
public: |
|||
enum class Type : u32 { |
|||
Is32Bit = 0, |
|||
Small64Bit = 1, |
|||
Large64Bit = 2, |
|||
Heap = 3, |
|||
Stack = 4, |
|||
Alias = 5, |
|||
Count, |
|||
}; |
|||
|
|||
private: |
|||
std::size_t bit_width{}; |
|||
std::size_t addr{}; |
|||
std::size_t size{}; |
|||
Type type{}; |
|||
|
|||
public: |
|||
static u64 GetAddressSpaceStart(std::size_t width, Type type); |
|||
static std::size_t GetAddressSpaceSize(std::size_t width, Type type); |
|||
|
|||
constexpr AddressSpaceInfo(std::size_t bit_width, std::size_t addr, std::size_t size, Type type) |
|||
: bit_width{bit_width}, addr{addr}, size{size}, type{type} {} |
|||
|
|||
constexpr std::size_t GetWidth() const { |
|||
return bit_width; |
|||
} |
|||
constexpr std::size_t GetAddress() const { |
|||
return addr; |
|||
} |
|||
constexpr std::size_t GetSize() const { |
|||
return size; |
|||
} |
|||
constexpr Type GetType() const { |
|||
return type; |
|||
} |
|||
}; |
|||
|
|||
} // namespace Kernel::Memory |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue