mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-06-12 09:48:01 -05:00
Merge pull request #9964 from liamwhite/typed-address
kernel: use KTypedAddress for addresses
This commit is contained in:
@ -76,22 +76,24 @@ void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout) {
|
||||
|
||||
void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout) {
|
||||
const size_t intended_memory_size = KSystemControl::Init::GetIntendedMemorySize();
|
||||
const PAddr physical_memory_base_address =
|
||||
const KPhysicalAddress physical_memory_base_address =
|
||||
KSystemControl::Init::GetKernelPhysicalBaseAddress(DramPhysicalAddress);
|
||||
|
||||
// Insert blocks into the tree.
|
||||
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
|
||||
physical_memory_base_address, intended_memory_size, KMemoryRegionType_Dram));
|
||||
GetInteger(physical_memory_base_address), intended_memory_size, KMemoryRegionType_Dram));
|
||||
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
|
||||
physical_memory_base_address, ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly));
|
||||
GetInteger(physical_memory_base_address), ReservedEarlyDramSize,
|
||||
KMemoryRegionType_DramReservedEarly));
|
||||
|
||||
// Insert the KTrace block at the end of Dram, if KTrace is enabled.
|
||||
static_assert(!IsKTraceEnabled || KTraceBufferSize > 0);
|
||||
if constexpr (IsKTraceEnabled) {
|
||||
const PAddr ktrace_buffer_phys_addr =
|
||||
const KPhysicalAddress ktrace_buffer_phys_addr =
|
||||
physical_memory_base_address + intended_memory_size - KTraceBufferSize;
|
||||
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
|
||||
ktrace_buffer_phys_addr, KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer));
|
||||
GetInteger(ktrace_buffer_phys_addr), KTraceBufferSize,
|
||||
KMemoryRegionType_KernelTraceBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
constexpr inline PAddr MainMemoryAddress = 0x80000000;
|
||||
constexpr inline KPhysicalAddress MainMemoryAddress = 0x80000000;
|
||||
|
||||
} // namespace Kernel
|
||||
|
@ -61,7 +61,7 @@ size_t KSystemControl::Init::GetIntendedMemorySize() {
|
||||
}
|
||||
}
|
||||
|
||||
PAddr KSystemControl::Init::GetKernelPhysicalBaseAddress(u64 base_address) {
|
||||
KPhysicalAddress KSystemControl::Init::GetKernelPhysicalBaseAddress(KPhysicalAddress base_address) {
|
||||
const size_t real_dram_size = KSystemControl::Init::GetRealMemorySize();
|
||||
const size_t intended_dram_size = KSystemControl::Init::GetIntendedMemorySize();
|
||||
if (intended_dram_size * 2 < real_dram_size) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
|
||||
namespace Kernel::Board::Nintendo::Nx {
|
||||
|
||||
@ -18,7 +18,7 @@ public:
|
||||
// Initialization.
|
||||
static std::size_t GetRealMemorySize();
|
||||
static std::size_t GetIntendedMemorySize();
|
||||
static PAddr GetKernelPhysicalBaseAddress(u64 base_address);
|
||||
static KPhysicalAddress GetKernelPhysicalBaseAddress(KPhysicalAddress base_address);
|
||||
static bool ShouldIncreaseThreadResourceLimit();
|
||||
static std::size_t GetApplicationPoolSize();
|
||||
static std::size_t GetAppletPoolSize();
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/physical_memory.h"
|
||||
|
||||
namespace Kernel {
|
||||
@ -36,7 +36,7 @@ struct CodeSet final {
|
||||
std::size_t offset = 0;
|
||||
|
||||
/// The address to map this segment to.
|
||||
VAddr addr = 0;
|
||||
KProcessAddress addr = 0;
|
||||
|
||||
/// The size of this segment in bytes.
|
||||
u32 size = 0;
|
||||
@ -82,7 +82,7 @@ struct CodeSet final {
|
||||
std::array<Segment, 3> segments;
|
||||
|
||||
/// The entry point address for this code set.
|
||||
VAddr entrypoint = 0;
|
||||
KProcessAddress entrypoint = 0;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
#include "core/device_memory.h"
|
||||
#include "core/hardware_properties.h"
|
||||
@ -30,6 +29,7 @@
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
#include "core/hle/kernel/k_thread_local_page.h"
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
|
||||
namespace Kernel::Init {
|
||||
|
||||
@ -104,17 +104,18 @@ static_assert(KernelPageBufferAdditionalSize ==
|
||||
|
||||
/// Helper function to translate from the slab virtual address to the reserved location in physical
|
||||
/// memory.
|
||||
static PAddr TranslateSlabAddrToPhysical(KMemoryLayout& memory_layout, VAddr slab_addr) {
|
||||
slab_addr -= memory_layout.GetSlabRegionAddress();
|
||||
return slab_addr + Core::DramMemoryMap::SlabHeapBase;
|
||||
static KPhysicalAddress TranslateSlabAddrToPhysical(KMemoryLayout& memory_layout,
|
||||
KVirtualAddress slab_addr) {
|
||||
slab_addr -= GetInteger(memory_layout.GetSlabRegionAddress());
|
||||
return GetInteger(slab_addr) + Core::DramMemoryMap::SlabHeapBase;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAddr address,
|
||||
size_t num_objects) {
|
||||
KVirtualAddress InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout,
|
||||
KVirtualAddress address, size_t num_objects) {
|
||||
|
||||
const size_t size = Common::AlignUp(sizeof(T) * num_objects, alignof(void*));
|
||||
VAddr start = Common::AlignUp(address, alignof(T));
|
||||
KVirtualAddress start = Common::AlignUp(GetInteger(address), alignof(T));
|
||||
|
||||
// This should use the virtual memory address passed in, but currently, we do not setup the
|
||||
// kernel virtual memory layout. Instead, we simply map these at a region of physical memory
|
||||
@ -195,7 +196,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
|
||||
auto& kernel = system.Kernel();
|
||||
|
||||
// Get the start of the slab region, since that's where we'll be working.
|
||||
VAddr address = memory_layout.GetSlabRegionAddress();
|
||||
KVirtualAddress address = memory_layout.GetSlabRegionAddress();
|
||||
|
||||
// Initialize slab type array to be in sorted order.
|
||||
std::array<KSlabType, KSlabType_Count> slab_types;
|
||||
@ -228,7 +229,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
|
||||
}
|
||||
|
||||
// Track the gaps, so that we can free them to the unused slab tree.
|
||||
VAddr gap_start = address;
|
||||
KVirtualAddress gap_start = address;
|
||||
size_t gap_size = 0;
|
||||
|
||||
for (size_t i = 0; i < slab_gaps.size(); i++) {
|
||||
@ -280,7 +281,7 @@ void KPageBufferSlabHeap::Initialize(Core::System& system) {
|
||||
// Allocate memory for the slab.
|
||||
constexpr auto AllocateOption = KMemoryManager::EncodeOption(
|
||||
KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
|
||||
const PAddr slab_address =
|
||||
const KPhysicalAddress slab_address =
|
||||
kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
|
||||
ASSERT(slab_address != 0);
|
||||
|
||||
|
@ -14,7 +14,7 @@ using namespace Common::Literals;
|
||||
|
||||
constexpr std::size_t InitialProcessBinarySizeMax = 12_MiB;
|
||||
|
||||
static inline PAddr GetInitialProcessBinaryPhysicalAddress() {
|
||||
static inline KPhysicalAddress GetInitialProcessBinaryPhysicalAddress() {
|
||||
return Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetKernelPhysicalBaseAddress(
|
||||
MainMemoryAddress);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
#include "core/hle/kernel/k_thread_queue.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/svc_results.h"
|
||||
#include "core/memory.h"
|
||||
@ -20,12 +21,12 @@ KAddressArbiter::~KAddressArbiter() = default;
|
||||
|
||||
namespace {
|
||||
|
||||
bool ReadFromUser(Core::System& system, s32* out, VAddr address) {
|
||||
*out = system.Memory().Read32(address);
|
||||
bool ReadFromUser(Core::System& system, s32* out, KProcessAddress address) {
|
||||
*out = system.Memory().Read32(GetInteger(address));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 value) {
|
||||
bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address, s32 value) {
|
||||
auto& monitor = system.Monitor();
|
||||
const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
|
||||
|
||||
@ -35,7 +36,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
|
||||
// TODO(bunnei): We should call CanAccessAtomic(..) here.
|
||||
|
||||
// Load the value from the address.
|
||||
const s32 current_value = static_cast<s32>(monitor.ExclusiveRead32(current_core, address));
|
||||
const s32 current_value =
|
||||
static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address)));
|
||||
|
||||
// Compare it to the desired one.
|
||||
if (current_value < value) {
|
||||
@ -43,7 +45,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
|
||||
const s32 decrement_value = current_value - 1;
|
||||
|
||||
// Decrement and try to store.
|
||||
if (!monitor.ExclusiveWrite32(current_core, address, static_cast<u32>(decrement_value))) {
|
||||
if (!monitor.ExclusiveWrite32(current_core, GetInteger(address),
|
||||
static_cast<u32>(decrement_value))) {
|
||||
// If we failed to store, try again.
|
||||
DecrementIfLessThan(system, out, address, value);
|
||||
}
|
||||
@ -57,7 +60,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 new_value) {
|
||||
bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 value,
|
||||
s32 new_value) {
|
||||
auto& monitor = system.Monitor();
|
||||
const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
|
||||
|
||||
@ -67,14 +71,16 @@ bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32
|
||||
// TODO(bunnei): We should call CanAccessAtomic(..) here.
|
||||
|
||||
// Load the value from the address.
|
||||
const s32 current_value = static_cast<s32>(monitor.ExclusiveRead32(current_core, address));
|
||||
const s32 current_value =
|
||||
static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address)));
|
||||
|
||||
// Compare it to the desired one.
|
||||
if (current_value == value) {
|
||||
// If equal, we want to try to write the new value.
|
||||
|
||||
// Try to store.
|
||||
if (!monitor.ExclusiveWrite32(current_core, address, static_cast<u32>(new_value))) {
|
||||
if (!monitor.ExclusiveWrite32(current_core, GetInteger(address),
|
||||
static_cast<u32>(new_value))) {
|
||||
// If we failed to store, try again.
|
||||
UpdateIfEqual(system, out, address, value, new_value);
|
||||
}
|
||||
@ -110,7 +116,7 @@ private:
|
||||
|
||||
} // namespace
|
||||
|
||||
Result KAddressArbiter::Signal(VAddr addr, s32 count) {
|
||||
Result KAddressArbiter::Signal(uint64_t addr, s32 count) {
|
||||
// Perform signaling.
|
||||
s32 num_waiters{};
|
||||
{
|
||||
@ -133,7 +139,7 @@ Result KAddressArbiter::Signal(VAddr addr, s32 count) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count) {
|
||||
Result KAddressArbiter::SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 count) {
|
||||
// Perform signaling.
|
||||
s32 num_waiters{};
|
||||
{
|
||||
@ -162,7 +168,7 @@ Result KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 cou
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count) {
|
||||
Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 value, s32 count) {
|
||||
// Perform signaling.
|
||||
s32 num_waiters{};
|
||||
{
|
||||
@ -225,7 +231,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 val
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) {
|
||||
Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s64 timeout) {
|
||||
// Prepare to wait.
|
||||
KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
|
||||
KHardwareTimer* timer{};
|
||||
@ -280,7 +286,7 @@ Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s6
|
||||
return cur_thread->GetWaitResult();
|
||||
}
|
||||
|
||||
Result KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
|
||||
Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) {
|
||||
// Prepare to wait.
|
||||
KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
|
||||
KHardwareTimer* timer{};
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
explicit KAddressArbiter(Core::System& system);
|
||||
~KAddressArbiter();
|
||||
|
||||
Result SignalToAddress(VAddr addr, Svc::SignalType type, s32 value, s32 count) {
|
||||
Result SignalToAddress(uint64_t addr, Svc::SignalType type, s32 value, s32 count) {
|
||||
switch (type) {
|
||||
case Svc::SignalType::Signal:
|
||||
R_RETURN(this->Signal(addr, count));
|
||||
@ -38,7 +38,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Result WaitForAddress(VAddr addr, Svc::ArbitrationType type, s32 value, s64 timeout) {
|
||||
Result WaitForAddress(uint64_t addr, Svc::ArbitrationType type, s32 value, s64 timeout) {
|
||||
switch (type) {
|
||||
case Svc::ArbitrationType::WaitIfLessThan:
|
||||
R_RETURN(WaitIfLessThan(addr, value, false, timeout));
|
||||
@ -52,11 +52,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Result Signal(VAddr addr, s32 count);
|
||||
Result SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count);
|
||||
Result SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count);
|
||||
Result WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout);
|
||||
Result WaitIfEqual(VAddr addr, s32 value, s64 timeout);
|
||||
Result Signal(uint64_t addr, s32 count);
|
||||
Result SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 count);
|
||||
Result SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 value, s32 count);
|
||||
Result WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s64 timeout);
|
||||
Result WaitIfEqual(uint64_t addr, s32 value, s64 timeout);
|
||||
|
||||
private:
|
||||
ThreadTree m_tree;
|
||||
|
@ -29,7 +29,8 @@ Result KClientSession::SendSyncRequest() {
|
||||
SCOPE_EXIT({ request->Close(); });
|
||||
|
||||
// Initialize the request.
|
||||
request->Initialize(nullptr, GetCurrentThread(m_kernel).GetTlsAddress(), MessageBufferSize);
|
||||
request->Initialize(nullptr, GetInteger(GetCurrentThread(m_kernel).GetTlsAddress()),
|
||||
MessageBufferSize);
|
||||
|
||||
// Send the request.
|
||||
R_RETURN(m_parent->GetServerSession().OnRequest(request));
|
||||
|
@ -19,7 +19,8 @@ namespace Kernel {
|
||||
KCodeMemory::KCodeMemory(KernelCore& kernel)
|
||||
: KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock(kernel) {}
|
||||
|
||||
Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) {
|
||||
Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddress addr,
|
||||
size_t size) {
|
||||
// Set members.
|
||||
m_owner = GetCurrentProcessPointer(m_kernel);
|
||||
|
||||
@ -63,7 +64,7 @@ void KCodeMemory::Finalize() {
|
||||
m_owner->Close();
|
||||
}
|
||||
|
||||
Result KCodeMemory::Map(VAddr address, size_t size) {
|
||||
Result KCodeMemory::Map(KProcessAddress address, size_t size) {
|
||||
// Validate the size.
|
||||
R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
|
||||
|
||||
@ -83,7 +84,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KCodeMemory::Unmap(VAddr address, size_t size) {
|
||||
Result KCodeMemory::Unmap(KProcessAddress address, size_t size) {
|
||||
// Validate the size.
|
||||
R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
|
||||
|
||||
@ -100,7 +101,7 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) {
|
||||
Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm) {
|
||||
// Validate the size.
|
||||
R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
|
||||
|
||||
@ -134,7 +135,7 @@ Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) {
|
||||
Result KCodeMemory::UnmapFromOwner(KProcessAddress address, size_t size) {
|
||||
// Validate the size.
|
||||
R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
|
||||
|
||||
|
@ -5,12 +5,12 @@
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/device_memory.h"
|
||||
#include "core/hle/kernel/k_auto_object.h"
|
||||
#include "core/hle/kernel/k_light_lock.h"
|
||||
#include "core/hle/kernel/k_page_group.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
#include "core/hle/kernel/svc_types.h"
|
||||
#include "core/hle/result.h"
|
||||
@ -31,13 +31,13 @@ class KCodeMemory final
|
||||
public:
|
||||
explicit KCodeMemory(KernelCore& kernel);
|
||||
|
||||
Result Initialize(Core::DeviceMemory& device_memory, VAddr address, size_t size);
|
||||
Result Initialize(Core::DeviceMemory& device_memory, KProcessAddress address, size_t size);
|
||||
void Finalize() override;
|
||||
|
||||
Result Map(VAddr address, size_t size);
|
||||
Result Unmap(VAddr address, size_t size);
|
||||
Result MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm);
|
||||
Result UnmapFromOwner(VAddr address, size_t size);
|
||||
Result Map(KProcessAddress address, size_t size);
|
||||
Result Unmap(KProcessAddress address, size_t size);
|
||||
Result MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm);
|
||||
Result UnmapFromOwner(KProcessAddress address, size_t size);
|
||||
|
||||
bool IsInitialized() const override {
|
||||
return m_is_initialized;
|
||||
@ -47,7 +47,7 @@ public:
|
||||
KProcess* GetOwner() const override {
|
||||
return m_owner;
|
||||
}
|
||||
VAddr GetSourceAddress() const {
|
||||
KProcessAddress GetSourceAddress() const {
|
||||
return m_address;
|
||||
}
|
||||
size_t GetSize() const {
|
||||
@ -57,7 +57,7 @@ public:
|
||||
private:
|
||||
std::optional<KPageGroup> m_page_group{};
|
||||
KProcess* m_owner{};
|
||||
VAddr m_address{};
|
||||
KProcessAddress m_address{};
|
||||
KLightLock m_lock;
|
||||
bool m_is_initialized{};
|
||||
bool m_is_owner_mapped{};
|
||||
|
@ -18,23 +18,23 @@ namespace Kernel {
|
||||
|
||||
namespace {
|
||||
|
||||
bool ReadFromUser(Core::System& system, u32* out, VAddr address) {
|
||||
*out = system.Memory().Read32(address);
|
||||
bool ReadFromUser(Core::System& system, u32* out, KProcessAddress address) {
|
||||
*out = system.Memory().Read32(GetInteger(address));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteToUser(Core::System& system, VAddr address, const u32* p) {
|
||||
system.Memory().Write32(address, *p);
|
||||
bool WriteToUser(Core::System& system, KProcessAddress address, const u32* p) {
|
||||
system.Memory().Write32(GetInteger(address), *p);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero,
|
||||
bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u32 if_zero,
|
||||
u32 new_orr_mask) {
|
||||
auto& monitor = system.Monitor();
|
||||
const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
|
||||
|
||||
// Load the value from the address.
|
||||
const auto expected = monitor.ExclusiveRead32(current_core, address);
|
||||
const auto expected = monitor.ExclusiveRead32(current_core, GetInteger(address));
|
||||
|
||||
// Orr in the new mask.
|
||||
u32 value = expected | new_orr_mask;
|
||||
@ -45,7 +45,7 @@ bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero
|
||||
}
|
||||
|
||||
// Try to store.
|
||||
if (!monitor.ExclusiveWrite32(current_core, address, value)) {
|
||||
if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), value)) {
|
||||
// If we failed to store, try again.
|
||||
return UpdateLockAtomic(system, out, address, if_zero, new_orr_mask);
|
||||
}
|
||||
@ -102,7 +102,7 @@ KConditionVariable::KConditionVariable(Core::System& system)
|
||||
|
||||
KConditionVariable::~KConditionVariable() = default;
|
||||
|
||||
Result KConditionVariable::SignalToAddress(VAddr addr) {
|
||||
Result KConditionVariable::SignalToAddress(KProcessAddress addr) {
|
||||
KThread* owner_thread = GetCurrentThreadPointer(m_kernel);
|
||||
|
||||
// Signal the address.
|
||||
@ -143,7 +143,7 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
|
||||
}
|
||||
}
|
||||
|
||||
Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) {
|
||||
Result KConditionVariable::WaitForAddress(Handle handle, KProcessAddress addr, u32 value) {
|
||||
KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
|
||||
ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(m_kernel);
|
||||
|
||||
@ -191,7 +191,7 @@ void KConditionVariable::SignalImpl(KThread* thread) {
|
||||
ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
|
||||
|
||||
// Update the tag.
|
||||
VAddr address = thread->GetAddressKey();
|
||||
KProcessAddress address = thread->GetAddressKey();
|
||||
u32 own_tag = thread->GetAddressKeyValue();
|
||||
|
||||
u32 prev_tag{};
|
||||
@ -262,7 +262,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
|
||||
}
|
||||
}
|
||||
|
||||
Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) {
|
||||
Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout) {
|
||||
// Prepare to wait.
|
||||
KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
|
||||
KHardwareTimer* timer{};
|
||||
|
@ -4,10 +4,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "core/hle/kernel/k_scheduler.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
@ -25,12 +25,12 @@ public:
|
||||
~KConditionVariable();
|
||||
|
||||
// Arbitration
|
||||
Result SignalToAddress(VAddr addr);
|
||||
Result WaitForAddress(Handle handle, VAddr addr, u32 value);
|
||||
Result SignalToAddress(KProcessAddress addr);
|
||||
Result WaitForAddress(Handle handle, KProcessAddress addr, u32 value);
|
||||
|
||||
// Condition variable
|
||||
void Signal(u64 cv_key, s32 count);
|
||||
Result Wait(VAddr addr, u64 key, u32 value, s64 timeout);
|
||||
Result Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout);
|
||||
|
||||
private:
|
||||
void SignalImpl(KThread* thread);
|
||||
|
@ -54,8 +54,8 @@ Result KDeviceAddressSpace::Detach(Svc::DeviceName device_name) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KDeviceAddressSpace::Map(KPageTable* page_table, VAddr process_address, size_t size,
|
||||
u64 device_address, u32 option, bool is_aligned) {
|
||||
Result KDeviceAddressSpace::Map(KPageTable* page_table, KProcessAddress process_address,
|
||||
size_t size, u64 device_address, u32 option, bool is_aligned) {
|
||||
// Check that the address falls within the space.
|
||||
R_UNLESS((m_space_address <= device_address &&
|
||||
device_address + size - 1 <= m_space_address + m_space_size - 1),
|
||||
@ -113,8 +113,8 @@ Result KDeviceAddressSpace::Map(KPageTable* page_table, VAddr process_address, s
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KDeviceAddressSpace::Unmap(KPageTable* page_table, VAddr process_address, size_t size,
|
||||
u64 device_address) {
|
||||
Result KDeviceAddressSpace::Unmap(KPageTable* page_table, KProcessAddress process_address,
|
||||
size_t size, u64 device_address) {
|
||||
// Check that the address falls within the space.
|
||||
R_UNLESS((m_space_address <= device_address &&
|
||||
device_address + size - 1 <= m_space_address + m_space_size - 1),
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_page_table.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
@ -31,23 +31,24 @@ public:
|
||||
Result Attach(Svc::DeviceName device_name);
|
||||
Result Detach(Svc::DeviceName device_name);
|
||||
|
||||
Result MapByForce(KPageTable* page_table, VAddr process_address, size_t size,
|
||||
Result MapByForce(KPageTable* page_table, KProcessAddress process_address, size_t size,
|
||||
u64 device_address, u32 option) {
|
||||
R_RETURN(this->Map(page_table, process_address, size, device_address, option, false));
|
||||
}
|
||||
|
||||
Result MapAligned(KPageTable* page_table, VAddr process_address, size_t size,
|
||||
Result MapAligned(KPageTable* page_table, KProcessAddress process_address, size_t size,
|
||||
u64 device_address, u32 option) {
|
||||
R_RETURN(this->Map(page_table, process_address, size, device_address, option, true));
|
||||
}
|
||||
|
||||
Result Unmap(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address);
|
||||
Result Unmap(KPageTable* page_table, KProcessAddress process_address, size_t size,
|
||||
u64 device_address);
|
||||
|
||||
static void Initialize();
|
||||
|
||||
private:
|
||||
Result Map(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address,
|
||||
u32 option, bool is_aligned);
|
||||
Result Map(KPageTable* page_table, KProcessAddress process_address, size_t size,
|
||||
u64 device_address, u32 option, bool is_aligned);
|
||||
|
||||
private:
|
||||
KLightLock m_lock;
|
||||
|
@ -6,9 +6,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_page_bitmap.h"
|
||||
#include "core/hle/kernel/k_spin_lock.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/memory_types.h"
|
||||
#include "core/hle/kernel/svc_results.h"
|
||||
|
||||
@ -26,23 +26,23 @@ public:
|
||||
KDynamicPageManager() = default;
|
||||
|
||||
template <typename T>
|
||||
T* GetPointer(VAddr addr) {
|
||||
T* GetPointer(KVirtualAddress addr) {
|
||||
return reinterpret_cast<T*>(m_backing_memory.data() + (addr - m_address));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* GetPointer(VAddr addr) const {
|
||||
const T* GetPointer(KVirtualAddress addr) const {
|
||||
return reinterpret_cast<T*>(m_backing_memory.data() + (addr - m_address));
|
||||
}
|
||||
|
||||
Result Initialize(VAddr memory, size_t size, size_t align) {
|
||||
Result Initialize(KVirtualAddress memory, size_t size, size_t align) {
|
||||
// We need to have positive size.
|
||||
R_UNLESS(size > 0, ResultOutOfMemory);
|
||||
m_backing_memory.resize(size);
|
||||
|
||||
// Set addresses.
|
||||
m_address = memory;
|
||||
m_aligned_address = Common::AlignDown(memory, align);
|
||||
m_aligned_address = Common::AlignDown(GetInteger(memory), align);
|
||||
|
||||
// Calculate extents.
|
||||
const size_t managed_size = m_address + size - m_aligned_address;
|
||||
@ -79,7 +79,7 @@ public:
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
VAddr GetAddress() const {
|
||||
KVirtualAddress GetAddress() const {
|
||||
return m_address;
|
||||
}
|
||||
size_t GetSize() const {
|
||||
@ -145,7 +145,8 @@ public:
|
||||
KScopedSpinLock lk(m_lock);
|
||||
|
||||
// Set the bit for the free page.
|
||||
size_t offset = (reinterpret_cast<uintptr_t>(pb) - m_aligned_address) / sizeof(PageBuffer);
|
||||
size_t offset =
|
||||
(reinterpret_cast<uint64_t>(pb) - GetInteger(m_aligned_address)) / sizeof(PageBuffer);
|
||||
m_page_bitmap.SetBit(offset);
|
||||
|
||||
// Decrement our used count.
|
||||
@ -158,8 +159,8 @@ private:
|
||||
size_t m_used{};
|
||||
size_t m_peak{};
|
||||
size_t m_count{};
|
||||
VAddr m_address{};
|
||||
VAddr m_aligned_address{};
|
||||
KVirtualAddress m_address{};
|
||||
KVirtualAddress m_aligned_address{};
|
||||
size_t m_size{};
|
||||
|
||||
// TODO(bunnei): Back by host memory until we emulate kernel virtual address space.
|
||||
|
@ -19,7 +19,7 @@ class KDynamicSlabHeap : protected impl::KSlabHeapImpl {
|
||||
public:
|
||||
constexpr KDynamicSlabHeap() = default;
|
||||
|
||||
constexpr VAddr GetAddress() const {
|
||||
constexpr KVirtualAddress GetAddress() const {
|
||||
return m_address;
|
||||
}
|
||||
constexpr size_t GetSize() const {
|
||||
@ -35,7 +35,7 @@ public:
|
||||
return m_count.load();
|
||||
}
|
||||
|
||||
constexpr bool IsInRange(VAddr addr) const {
|
||||
constexpr bool IsInRange(KVirtualAddress addr) const {
|
||||
return this->GetAddress() <= addr && addr <= this->GetAddress() + this->GetSize() - 1;
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ private:
|
||||
std::atomic<size_t> m_used{};
|
||||
std::atomic<size_t> m_peak{};
|
||||
std::atomic<size_t> m_count{};
|
||||
VAddr m_address{};
|
||||
KVirtualAddress m_address{};
|
||||
size_t m_size{};
|
||||
};
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/intrusive_red_black_tree.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/memory_types.h"
|
||||
#include "core/hle/kernel/svc_types.h"
|
||||
|
||||
@ -282,7 +282,7 @@ class KMemoryBlock : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>
|
||||
private:
|
||||
u16 m_device_disable_merge_left_count{};
|
||||
u16 m_device_disable_merge_right_count{};
|
||||
VAddr m_address{};
|
||||
KProcessAddress m_address{};
|
||||
size_t m_num_pages{};
|
||||
KMemoryState m_memory_state{KMemoryState::None};
|
||||
u16 m_ipc_lock_count{};
|
||||
@ -306,7 +306,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr VAddr GetAddress() const {
|
||||
constexpr KProcessAddress GetAddress() const {
|
||||
return m_address;
|
||||
}
|
||||
|
||||
@ -318,11 +318,11 @@ public:
|
||||
return this->GetNumPages() * PageSize;
|
||||
}
|
||||
|
||||
constexpr VAddr GetEndAddress() const {
|
||||
constexpr KProcessAddress GetEndAddress() const {
|
||||
return this->GetAddress() + this->GetSize();
|
||||
}
|
||||
|
||||
constexpr VAddr GetLastAddress() const {
|
||||
constexpr KProcessAddress GetLastAddress() const {
|
||||
return this->GetEndAddress() - 1;
|
||||
}
|
||||
|
||||
@ -348,7 +348,7 @@ public:
|
||||
|
||||
constexpr KMemoryInfo GetMemoryInfo() const {
|
||||
return {
|
||||
.m_address = this->GetAddress(),
|
||||
.m_address = GetInteger(this->GetAddress()),
|
||||
.m_size = this->GetSize(),
|
||||
.m_state = m_memory_state,
|
||||
.m_device_disable_merge_left_count = m_device_disable_merge_left_count,
|
||||
@ -366,12 +366,12 @@ public:
|
||||
public:
|
||||
explicit KMemoryBlock() = default;
|
||||
|
||||
constexpr KMemoryBlock(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
|
||||
constexpr KMemoryBlock(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p,
|
||||
KMemoryAttribute attr)
|
||||
: Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(), m_address(addr), m_num_pages(np),
|
||||
m_memory_state(ms), m_permission(p), m_attribute(attr) {}
|
||||
|
||||
constexpr void Initialize(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
|
||||
constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p,
|
||||
KMemoryAttribute attr) {
|
||||
m_device_disable_merge_left_count = 0;
|
||||
m_device_disable_merge_right_count = 0;
|
||||
@ -408,7 +408,7 @@ public:
|
||||
KMemoryBlockDisableMergeAttribute::None;
|
||||
}
|
||||
|
||||
constexpr bool Contains(VAddr addr) const {
|
||||
constexpr bool Contains(KProcessAddress addr) const {
|
||||
return this->GetAddress() <= addr && addr <= this->GetEndAddress();
|
||||
}
|
||||
|
||||
@ -443,10 +443,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void Split(KMemoryBlock* block, VAddr addr) {
|
||||
constexpr void Split(KMemoryBlock* block, KProcessAddress addr) {
|
||||
ASSERT(this->GetAddress() < addr);
|
||||
ASSERT(this->Contains(addr));
|
||||
ASSERT(Common::IsAligned(addr, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
|
||||
|
||||
block->m_address = m_address;
|
||||
block->m_num_pages = (addr - this->GetAddress()) / PageSize;
|
||||
|
@ -7,7 +7,8 @@ namespace Kernel {
|
||||
|
||||
KMemoryBlockManager::KMemoryBlockManager() = default;
|
||||
|
||||
Result KMemoryBlockManager::Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager) {
|
||||
Result KMemoryBlockManager::Initialize(KProcessAddress st, KProcessAddress nd,
|
||||
KMemoryBlockSlabManager* slab_manager) {
|
||||
// Allocate a block to encapsulate the address space, insert it into the tree.
|
||||
KMemoryBlock* start_block = slab_manager->Allocate();
|
||||
R_UNLESS(start_block != nullptr, ResultOutOfResource);
|
||||
@ -15,8 +16,8 @@ Result KMemoryBlockManager::Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManag
|
||||
// Set our start and end.
|
||||
m_start_address = st;
|
||||
m_end_address = nd;
|
||||
ASSERT(Common::IsAligned(m_start_address, PageSize));
|
||||
ASSERT(Common::IsAligned(m_end_address, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(m_start_address), PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(m_end_address), PageSize));
|
||||
|
||||
// Initialize and insert the block.
|
||||
start_block->Initialize(m_start_address, (m_end_address - m_start_address) / PageSize,
|
||||
@ -40,12 +41,13 @@ void KMemoryBlockManager::Finalize(KMemoryBlockSlabManager* slab_manager,
|
||||
ASSERT(m_memory_block_tree.empty());
|
||||
}
|
||||
|
||||
VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pages,
|
||||
size_t num_pages, size_t alignment, size_t offset,
|
||||
size_t guard_pages) const {
|
||||
KProcessAddress KMemoryBlockManager::FindFreeArea(KProcessAddress region_start,
|
||||
size_t region_num_pages, size_t num_pages,
|
||||
size_t alignment, size_t offset,
|
||||
size_t guard_pages) const {
|
||||
if (num_pages > 0) {
|
||||
const VAddr region_end = region_start + region_num_pages * PageSize;
|
||||
const VAddr region_last = region_end - 1;
|
||||
const KProcessAddress region_end = region_start + region_num_pages * PageSize;
|
||||
const KProcessAddress region_last = region_end - 1;
|
||||
for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend();
|
||||
it++) {
|
||||
const KMemoryInfo info = it->GetMemoryInfo();
|
||||
@ -56,17 +58,19 @@ VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pa
|
||||
continue;
|
||||
}
|
||||
|
||||
VAddr area = (info.GetAddress() <= region_start) ? region_start : info.GetAddress();
|
||||
KProcessAddress area =
|
||||
(info.GetAddress() <= GetInteger(region_start)) ? region_start : info.GetAddress();
|
||||
area += guard_pages * PageSize;
|
||||
|
||||
const VAddr offset_area = Common::AlignDown(area, alignment) + offset;
|
||||
const KProcessAddress offset_area =
|
||||
Common::AlignDown(GetInteger(area), alignment) + offset;
|
||||
area = (area <= offset_area) ? offset_area : offset_area + alignment;
|
||||
|
||||
const VAddr area_end = area + num_pages * PageSize + guard_pages * PageSize;
|
||||
const VAddr area_last = area_end - 1;
|
||||
const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize;
|
||||
const KProcessAddress area_last = area_end - 1;
|
||||
|
||||
if (info.GetAddress() <= area && area < area_last && area_last <= region_last &&
|
||||
area_last <= info.GetLastAddress()) {
|
||||
if (info.GetAddress() <= GetInteger(area) && area < area_last &&
|
||||
area_last <= region_last && area_last <= info.GetLastAddress()) {
|
||||
return area;
|
||||
}
|
||||
}
|
||||
@ -76,7 +80,7 @@ VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pa
|
||||
}
|
||||
|
||||
void KMemoryBlockManager::CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator,
|
||||
VAddr address, size_t num_pages) {
|
||||
KProcessAddress address, size_t num_pages) {
|
||||
// Find the iterator now that we've updated.
|
||||
iterator it = this->FindIterator(address);
|
||||
if (address != m_start_address) {
|
||||
@ -104,18 +108,18 @@ void KMemoryBlockManager::CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator*
|
||||
}
|
||||
}
|
||||
|
||||
void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
|
||||
size_t num_pages, KMemoryState state, KMemoryPermission perm,
|
||||
KMemoryAttribute attr,
|
||||
void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator,
|
||||
KProcessAddress address, size_t num_pages, KMemoryState state,
|
||||
KMemoryPermission perm, KMemoryAttribute attr,
|
||||
KMemoryBlockDisableMergeAttribute set_disable_attr,
|
||||
KMemoryBlockDisableMergeAttribute clear_disable_attr) {
|
||||
// Ensure for auditing that we never end up with an invalid tree.
|
||||
KScopedMemoryBlockManagerAuditor auditor(this);
|
||||
ASSERT(Common::IsAligned(address, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(address), PageSize));
|
||||
ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
|
||||
KMemoryAttribute::None);
|
||||
|
||||
VAddr cur_address = address;
|
||||
KProcessAddress cur_address = address;
|
||||
size_t remaining_pages = num_pages;
|
||||
iterator it = this->FindIterator(address);
|
||||
|
||||
@ -168,17 +172,17 @@ void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator,
|
||||
}
|
||||
|
||||
void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator,
|
||||
VAddr address, size_t num_pages, KMemoryState test_state,
|
||||
KMemoryPermission test_perm, KMemoryAttribute test_attr,
|
||||
KMemoryState state, KMemoryPermission perm,
|
||||
KMemoryAttribute attr) {
|
||||
KProcessAddress address, size_t num_pages,
|
||||
KMemoryState test_state, KMemoryPermission test_perm,
|
||||
KMemoryAttribute test_attr, KMemoryState state,
|
||||
KMemoryPermission perm, KMemoryAttribute attr) {
|
||||
// Ensure for auditing that we never end up with an invalid tree.
|
||||
KScopedMemoryBlockManagerAuditor auditor(this);
|
||||
ASSERT(Common::IsAligned(address, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(address), PageSize));
|
||||
ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
|
||||
KMemoryAttribute::None);
|
||||
|
||||
VAddr cur_address = address;
|
||||
KProcessAddress cur_address = address;
|
||||
size_t remaining_pages = num_pages;
|
||||
iterator it = this->FindIterator(address);
|
||||
|
||||
@ -230,18 +234,18 @@ void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allo
|
||||
this->CoalesceForUpdate(allocator, address, num_pages);
|
||||
}
|
||||
|
||||
void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
|
||||
size_t num_pages, MemoryBlockLockFunction lock_func,
|
||||
KMemoryPermission perm) {
|
||||
void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator,
|
||||
KProcessAddress address, size_t num_pages,
|
||||
MemoryBlockLockFunction lock_func, KMemoryPermission perm) {
|
||||
// Ensure for auditing that we never end up with an invalid tree.
|
||||
KScopedMemoryBlockManagerAuditor auditor(this);
|
||||
ASSERT(Common::IsAligned(address, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(address), PageSize));
|
||||
|
||||
VAddr cur_address = address;
|
||||
KProcessAddress cur_address = address;
|
||||
size_t remaining_pages = num_pages;
|
||||
iterator it = this->FindIterator(address);
|
||||
|
||||
const VAddr end_address = address + (num_pages * PageSize);
|
||||
const KProcessAddress end_address = address + (num_pages * PageSize);
|
||||
|
||||
while (remaining_pages > 0) {
|
||||
const size_t remaining_size = remaining_pages * PageSize;
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include <functional>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_dynamic_resource_manager.h"
|
||||
#include "core/hle/kernel/k_memory_block.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@ -85,9 +85,10 @@ public:
|
||||
public:
|
||||
KMemoryBlockManager();
|
||||
|
||||
using HostUnmapCallback = std::function<void(VAddr, u64)>;
|
||||
using HostUnmapCallback = std::function<void(Common::ProcessAddress, u64)>;
|
||||
|
||||
Result Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager);
|
||||
Result Initialize(KProcessAddress st, KProcessAddress nd,
|
||||
KMemoryBlockSlabManager* slab_manager);
|
||||
void Finalize(KMemoryBlockSlabManager* slab_manager, HostUnmapCallback&& host_unmap_callback);
|
||||
|
||||
iterator end() {
|
||||
@ -100,27 +101,28 @@ public:
|
||||
return m_memory_block_tree.cend();
|
||||
}
|
||||
|
||||
VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
|
||||
size_t alignment, size_t offset, size_t guard_pages) const;
|
||||
KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
|
||||
size_t num_pages, size_t alignment, size_t offset,
|
||||
size_t guard_pages) const;
|
||||
|
||||
void Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages,
|
||||
KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr,
|
||||
void Update(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
|
||||
size_t num_pages, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr,
|
||||
KMemoryBlockDisableMergeAttribute set_disable_attr,
|
||||
KMemoryBlockDisableMergeAttribute clear_disable_attr);
|
||||
void UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages,
|
||||
MemoryBlockLockFunction lock_func, KMemoryPermission perm);
|
||||
void UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
|
||||
size_t num_pages, MemoryBlockLockFunction lock_func, KMemoryPermission perm);
|
||||
|
||||
void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
|
||||
void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
|
||||
size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm,
|
||||
KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm,
|
||||
KMemoryAttribute attr);
|
||||
|
||||
iterator FindIterator(VAddr address) const {
|
||||
iterator FindIterator(KProcessAddress address) const {
|
||||
return m_memory_block_tree.find(KMemoryBlock(
|
||||
address, 1, KMemoryState::Free, KMemoryPermission::None, KMemoryAttribute::None));
|
||||
}
|
||||
|
||||
const KMemoryBlock* FindBlock(VAddr address) const {
|
||||
const KMemoryBlock* FindBlock(KProcessAddress address) const {
|
||||
if (const_iterator it = this->FindIterator(address); it != m_memory_block_tree.end()) {
|
||||
return std::addressof(*it);
|
||||
}
|
||||
@ -132,12 +134,12 @@ public:
|
||||
bool CheckState() const;
|
||||
|
||||
private:
|
||||
void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
|
||||
void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
|
||||
size_t num_pages);
|
||||
|
||||
MemoryBlockTree m_memory_block_tree;
|
||||
VAddr m_start_address{};
|
||||
VAddr m_end_address{};
|
||||
KProcessAddress m_start_address{};
|
||||
KProcessAddress m_end_address{};
|
||||
};
|
||||
|
||||
class KScopedMemoryBlockManagerAuditor {
|
||||
|
@ -85,7 +85,8 @@ bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_at
|
||||
return true;
|
||||
}
|
||||
|
||||
VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id) {
|
||||
KVirtualAddress KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment,
|
||||
u32 type_id) {
|
||||
// We want to find the total extents of the type id.
|
||||
const auto extents = this->GetDerivedRegionExtents(static_cast<KMemoryRegionType>(type_id));
|
||||
|
||||
@ -130,11 +131,13 @@ KMemoryLayout::KMemoryLayout()
|
||||
m_virtual_linear_tree{m_memory_region_allocator}, m_physical_linear_tree{
|
||||
m_memory_region_allocator} {}
|
||||
|
||||
void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
|
||||
VAddr linear_virtual_start) {
|
||||
void KMemoryLayout::InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start,
|
||||
KVirtualAddress linear_virtual_start) {
|
||||
// Set static differences.
|
||||
m_linear_phys_to_virt_diff = linear_virtual_start - aligned_linear_phys_start;
|
||||
m_linear_virt_to_phys_diff = aligned_linear_phys_start - linear_virtual_start;
|
||||
m_linear_phys_to_virt_diff =
|
||||
GetInteger(linear_virtual_start) - GetInteger(aligned_linear_phys_start);
|
||||
m_linear_virt_to_phys_diff =
|
||||
GetInteger(aligned_linear_phys_start) - GetInteger(linear_virtual_start);
|
||||
|
||||
// Initialize linear trees.
|
||||
for (auto& region : GetPhysicalMemoryRegionTree()) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "core/device_memory.h"
|
||||
#include "core/hle/kernel/k_memory_region.h"
|
||||
#include "core/hle/kernel/k_memory_region_type.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/memory_types.h"
|
||||
|
||||
namespace Kernel {
|
||||
@ -69,10 +70,11 @@ constexpr std::size_t KernelResourceSize = KernelPageTableHeapSize + KernelIniti
|
||||
|
||||
//! NB: Use KThread::GetAddressKeyIsKernel().
|
||||
//! See explanation for deviation of GetAddressKey.
|
||||
bool IsKernelAddressKey(VAddr key) = delete;
|
||||
bool IsKernelAddressKey(KProcessAddress key) = delete;
|
||||
|
||||
constexpr bool IsKernelAddress(VAddr address) {
|
||||
return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd;
|
||||
constexpr bool IsKernelAddress(KProcessAddress address) {
|
||||
return KernelVirtualAddressSpaceBase <= GetInteger(address) &&
|
||||
address < KernelVirtualAddressSpaceEnd;
|
||||
}
|
||||
|
||||
class KMemoryLayout final {
|
||||
@ -104,38 +106,38 @@ public:
|
||||
return m_physical_linear_tree;
|
||||
}
|
||||
|
||||
VAddr GetLinearVirtualAddress(PAddr address) const {
|
||||
return address + m_linear_phys_to_virt_diff;
|
||||
KVirtualAddress GetLinearVirtualAddress(KPhysicalAddress address) const {
|
||||
return GetInteger(address) + m_linear_phys_to_virt_diff;
|
||||
}
|
||||
PAddr GetLinearPhysicalAddress(VAddr address) const {
|
||||
return address + m_linear_virt_to_phys_diff;
|
||||
KPhysicalAddress GetLinearPhysicalAddress(KVirtualAddress address) const {
|
||||
return GetInteger(address) + m_linear_virt_to_phys_diff;
|
||||
}
|
||||
|
||||
const KMemoryRegion* FindVirtual(VAddr address) const {
|
||||
const KMemoryRegion* FindVirtual(KVirtualAddress address) const {
|
||||
return Find(address, GetVirtualMemoryRegionTree());
|
||||
}
|
||||
const KMemoryRegion* FindPhysical(PAddr address) const {
|
||||
const KMemoryRegion* FindPhysical(KPhysicalAddress address) const {
|
||||
return Find(address, GetPhysicalMemoryRegionTree());
|
||||
}
|
||||
|
||||
const KMemoryRegion* FindVirtualLinear(VAddr address) const {
|
||||
const KMemoryRegion* FindVirtualLinear(KVirtualAddress address) const {
|
||||
return Find(address, GetVirtualLinearMemoryRegionTree());
|
||||
}
|
||||
const KMemoryRegion* FindPhysicalLinear(PAddr address) const {
|
||||
const KMemoryRegion* FindPhysicalLinear(KPhysicalAddress address) const {
|
||||
return Find(address, GetPhysicalLinearMemoryRegionTree());
|
||||
}
|
||||
|
||||
VAddr GetMainStackTopAddress(s32 core_id) const {
|
||||
KVirtualAddress GetMainStackTopAddress(s32 core_id) const {
|
||||
return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscMainStack);
|
||||
}
|
||||
VAddr GetIdleStackTopAddress(s32 core_id) const {
|
||||
KVirtualAddress GetIdleStackTopAddress(s32 core_id) const {
|
||||
return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscIdleStack);
|
||||
}
|
||||
VAddr GetExceptionStackTopAddress(s32 core_id) const {
|
||||
KVirtualAddress GetExceptionStackTopAddress(s32 core_id) const {
|
||||
return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscExceptionStack);
|
||||
}
|
||||
|
||||
VAddr GetSlabRegionAddress() const {
|
||||
KVirtualAddress GetSlabRegionAddress() const {
|
||||
return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelSlab))
|
||||
.GetAddress();
|
||||
}
|
||||
@ -143,10 +145,10 @@ public:
|
||||
const KMemoryRegion& GetDeviceRegion(KMemoryRegionType type) const {
|
||||
return Dereference(GetPhysicalMemoryRegionTree().FindFirstDerived(type));
|
||||
}
|
||||
PAddr GetDevicePhysicalAddress(KMemoryRegionType type) const {
|
||||
KPhysicalAddress GetDevicePhysicalAddress(KMemoryRegionType type) const {
|
||||
return GetDeviceRegion(type).GetAddress();
|
||||
}
|
||||
VAddr GetDeviceVirtualAddress(KMemoryRegionType type) const {
|
||||
KVirtualAddress GetDeviceVirtualAddress(KMemoryRegionType type) const {
|
||||
return GetDeviceRegion(type).GetPairAddress();
|
||||
}
|
||||
|
||||
@ -175,11 +177,11 @@ public:
|
||||
KMemoryRegionType_VirtualDramKernelSecureAppletMemory));
|
||||
}
|
||||
|
||||
const KMemoryRegion& GetVirtualLinearRegion(VAddr address) const {
|
||||
const KMemoryRegion& GetVirtualLinearRegion(KVirtualAddress address) const {
|
||||
return Dereference(FindVirtualLinear(address));
|
||||
}
|
||||
|
||||
const KMemoryRegion& GetPhysicalLinearRegion(PAddr address) const {
|
||||
const KMemoryRegion& GetPhysicalLinearRegion(KPhysicalAddress address) const {
|
||||
return Dereference(FindPhysicalLinear(address));
|
||||
}
|
||||
|
||||
@ -193,29 +195,32 @@ public:
|
||||
return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DTB);
|
||||
}
|
||||
|
||||
bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
|
||||
bool IsHeapPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address) const {
|
||||
return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
|
||||
KMemoryRegionType_DramUserPool);
|
||||
}
|
||||
bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address) const {
|
||||
bool IsHeapVirtualAddress(const KMemoryRegion*& region, KVirtualAddress address) const {
|
||||
return IsTypedAddress(region, address, GetVirtualLinearMemoryRegionTree(),
|
||||
KMemoryRegionType_VirtualDramUserPool);
|
||||
}
|
||||
|
||||
bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address, size_t size) const {
|
||||
bool IsHeapPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address,
|
||||
size_t size) const {
|
||||
return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
|
||||
KMemoryRegionType_DramUserPool);
|
||||
}
|
||||
bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address, size_t size) const {
|
||||
bool IsHeapVirtualAddress(const KMemoryRegion*& region, KVirtualAddress address,
|
||||
size_t size) const {
|
||||
return IsTypedAddress(region, address, size, GetVirtualLinearMemoryRegionTree(),
|
||||
KMemoryRegionType_VirtualDramUserPool);
|
||||
}
|
||||
|
||||
bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
|
||||
bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region,
|
||||
KPhysicalAddress address) const {
|
||||
return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
|
||||
static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped));
|
||||
}
|
||||
bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address,
|
||||
bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address,
|
||||
size_t size) const {
|
||||
return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
|
||||
static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped));
|
||||
@ -234,8 +239,8 @@ public:
|
||||
return std::make_pair(total_size, kernel_size);
|
||||
}
|
||||
|
||||
void InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
|
||||
VAddr linear_virtual_start);
|
||||
void InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start,
|
||||
KVirtualAddress linear_virtual_start);
|
||||
static size_t GetResourceRegionSizeForInit(bool use_extra_resource);
|
||||
|
||||
auto GetKernelRegionExtents() const {
|
||||
@ -261,8 +266,8 @@ public:
|
||||
|
||||
auto GetLinearRegionVirtualExtents() const {
|
||||
const auto physical = GetLinearRegionPhysicalExtents();
|
||||
return KMemoryRegion(GetLinearVirtualAddress(physical.GetAddress()),
|
||||
GetLinearVirtualAddress(physical.GetLastAddress()), 0,
|
||||
return KMemoryRegion(GetInteger(GetLinearVirtualAddress(physical.GetAddress())),
|
||||
GetInteger(GetLinearVirtualAddress(physical.GetLastAddress())), 0,
|
||||
KMemoryRegionType_None);
|
||||
}
|
||||
|
||||
@ -334,12 +339,12 @@ private:
|
||||
static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address,
|
||||
const KMemoryRegionTree& tree, KMemoryRegionType type) {
|
||||
// Check if the cached region already contains the address.
|
||||
if (region != nullptr && region->Contains(address)) {
|
||||
if (region != nullptr && region->Contains(GetInteger(address))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the containing region, and update the cache.
|
||||
if (const KMemoryRegion* found = tree.Find(address);
|
||||
if (const KMemoryRegion* found = tree.Find(GetInteger(address));
|
||||
found != nullptr && found->IsDerivedFrom(type)) {
|
||||
region = found;
|
||||
return true;
|
||||
@ -352,11 +357,12 @@ private:
|
||||
static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, size_t size,
|
||||
const KMemoryRegionTree& tree, KMemoryRegionType type) {
|
||||
// Get the end of the checked region.
|
||||
const u64 last_address = address + size - 1;
|
||||
const u64 last_address = GetInteger(address) + size - 1;
|
||||
|
||||
// Walk the tree to verify the region is correct.
|
||||
const KMemoryRegion* cur =
|
||||
(region != nullptr && region->Contains(address)) ? region : tree.Find(address);
|
||||
const KMemoryRegion* cur = (region != nullptr && region->Contains(GetInteger(address)))
|
||||
? region
|
||||
: tree.Find(GetInteger(address));
|
||||
while (cur != nullptr && cur->IsDerivedFrom(type)) {
|
||||
if (last_address <= cur->GetLastAddress()) {
|
||||
region = cur;
|
||||
@ -370,7 +376,7 @@ private:
|
||||
|
||||
template <typename AddressType>
|
||||
static const KMemoryRegion* Find(AddressType address, const KMemoryRegionTree& tree) {
|
||||
return tree.Find(address);
|
||||
return tree.Find(GetInteger(address));
|
||||
}
|
||||
|
||||
static KMemoryRegion& Dereference(KMemoryRegion* region) {
|
||||
@ -383,7 +389,7 @@ private:
|
||||
return *region;
|
||||
}
|
||||
|
||||
VAddr GetStackTopAddress(s32 core_id, KMemoryRegionType type) const {
|
||||
KVirtualAddress GetStackTopAddress(s32 core_id, KMemoryRegionType type) const {
|
||||
const auto& region = Dereference(
|
||||
GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id)));
|
||||
ASSERT(region.GetEndAddress() != 0);
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "core/core.h"
|
||||
#include "core/device_memory.h"
|
||||
@ -44,10 +43,10 @@ KMemoryManager::KMemoryManager(Core::System& system)
|
||||
KLightLock{system.Kernel()},
|
||||
} {}
|
||||
|
||||
void KMemoryManager::Initialize(VAddr management_region, size_t management_region_size) {
|
||||
void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size) {
|
||||
|
||||
// Clear the management region to zero.
|
||||
const VAddr management_region_end = management_region + management_region_size;
|
||||
const KVirtualAddress management_region_end = management_region + management_region_size;
|
||||
// std::memset(GetVoidPointer(management_region), 0, management_region_size);
|
||||
|
||||
// Reset our manager count.
|
||||
@ -56,7 +55,7 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio
|
||||
// Traverse the virtual memory layout tree, initializing each manager as appropriate.
|
||||
while (m_num_managers != MaxManagerCount) {
|
||||
// Locate the region that should initialize the current manager.
|
||||
PAddr region_address = 0;
|
||||
KPhysicalAddress region_address = 0;
|
||||
size_t region_size = 0;
|
||||
Pool region_pool = Pool::Count;
|
||||
for (const auto& it : m_system.Kernel().MemoryLayout().GetPhysicalMemoryRegionTree()) {
|
||||
@ -70,8 +69,8 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio
|
||||
continue;
|
||||
}
|
||||
|
||||
const PAddr cur_start = it.GetAddress();
|
||||
const PAddr cur_end = it.GetEndAddress();
|
||||
const KPhysicalAddress cur_start = it.GetAddress();
|
||||
const KPhysicalAddress cur_end = it.GetEndAddress();
|
||||
|
||||
// Validate the region.
|
||||
ASSERT(cur_end != 0);
|
||||
@ -119,17 +118,17 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio
|
||||
|
||||
// Free each region to its corresponding heap.
|
||||
size_t reserved_sizes[MaxManagerCount] = {};
|
||||
const PAddr ini_start = GetInitialProcessBinaryPhysicalAddress();
|
||||
const PAddr ini_end = ini_start + InitialProcessBinarySizeMax;
|
||||
const PAddr ini_last = ini_end - 1;
|
||||
const KPhysicalAddress ini_start = GetInitialProcessBinaryPhysicalAddress();
|
||||
const KPhysicalAddress ini_end = ini_start + InitialProcessBinarySizeMax;
|
||||
const KPhysicalAddress ini_last = ini_end - 1;
|
||||
for (const auto& it : m_system.Kernel().MemoryLayout().GetPhysicalMemoryRegionTree()) {
|
||||
if (it.IsDerivedFrom(KMemoryRegionType_DramUserPool)) {
|
||||
// Get the manager for the region.
|
||||
auto& manager = m_managers[it.GetAttributes()];
|
||||
|
||||
const PAddr cur_start = it.GetAddress();
|
||||
const PAddr cur_last = it.GetLastAddress();
|
||||
const PAddr cur_end = it.GetEndAddress();
|
||||
const KPhysicalAddress cur_start = it.GetAddress();
|
||||
const KPhysicalAddress cur_last = it.GetLastAddress();
|
||||
const KPhysicalAddress cur_end = it.GetEndAddress();
|
||||
|
||||
if (cur_start <= ini_start && ini_last <= cur_last) {
|
||||
// Free memory before the ini to the heap.
|
||||
@ -175,7 +174,8 @@ void KMemoryManager::FinalizeOptimizedMemory(u64 process_id, Pool pool) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
PAddr KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option) {
|
||||
KPhysicalAddress KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages,
|
||||
u32 option) {
|
||||
// Early return if we're allocating no pages.
|
||||
if (num_pages == 0) {
|
||||
return 0;
|
||||
@ -190,7 +190,7 @@ PAddr KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_p
|
||||
|
||||
// Loop, trying to iterate from each block.
|
||||
Impl* chosen_manager = nullptr;
|
||||
PAddr allocated_block = 0;
|
||||
KPhysicalAddress allocated_block = 0;
|
||||
for (chosen_manager = this->GetFirstManager(pool, dir); chosen_manager != nullptr;
|
||||
chosen_manager = this->GetNextManager(chosen_manager, dir)) {
|
||||
allocated_block = chosen_manager->AllocateAligned(heap_index, num_pages, align_pages);
|
||||
@ -239,7 +239,7 @@ Result KMemoryManager::AllocatePageGroupImpl(KPageGroup* out, size_t num_pages,
|
||||
cur_manager = this->GetNextManager(cur_manager, dir)) {
|
||||
while (num_pages >= pages_per_alloc) {
|
||||
// Allocate a block.
|
||||
PAddr allocated_block = cur_manager->AllocateBlock(index, random);
|
||||
KPhysicalAddress allocated_block = cur_manager->AllocateBlock(index, random);
|
||||
if (allocated_block == 0) {
|
||||
break;
|
||||
}
|
||||
@ -286,7 +286,7 @@ Result KMemoryManager::AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 op
|
||||
|
||||
// Open the first reference to the pages.
|
||||
for (const auto& block : *out) {
|
||||
PAddr cur_address = block.GetAddress();
|
||||
KPhysicalAddress cur_address = block.GetAddress();
|
||||
size_t remaining_pages = block.GetNumPages();
|
||||
while (remaining_pages > 0) {
|
||||
// Get the manager for the current address.
|
||||
@ -337,7 +337,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
|
||||
// Iterate over the allocated blocks.
|
||||
for (const auto& block : *out) {
|
||||
// Get the block extents.
|
||||
const PAddr block_address = block.GetAddress();
|
||||
const KPhysicalAddress block_address = block.GetAddress();
|
||||
const size_t block_pages = block.GetNumPages();
|
||||
|
||||
// If it has no pages, we don't need to do anything.
|
||||
@ -348,7 +348,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
|
||||
// Fill all the pages that we need to fill.
|
||||
bool any_new = false;
|
||||
{
|
||||
PAddr cur_address = block_address;
|
||||
KPhysicalAddress cur_address = block_address;
|
||||
size_t remaining_pages = block_pages;
|
||||
while (remaining_pages > 0) {
|
||||
// Get the manager for the current address.
|
||||
@ -369,7 +369,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
|
||||
// If there are new pages, update tracking for the allocation.
|
||||
if (any_new) {
|
||||
// Update tracking for the allocation.
|
||||
PAddr cur_address = block_address;
|
||||
KPhysicalAddress cur_address = block_address;
|
||||
size_t remaining_pages = block_pages;
|
||||
while (remaining_pages > 0) {
|
||||
// Get the manager for the current address.
|
||||
@ -400,8 +400,9 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr management,
|
||||
VAddr management_end, Pool p) {
|
||||
size_t KMemoryManager::Impl::Initialize(KPhysicalAddress address, size_t size,
|
||||
KVirtualAddress management, KVirtualAddress management_end,
|
||||
Pool p) {
|
||||
// Calculate management sizes.
|
||||
const size_t ref_count_size = (size / PageSize) * sizeof(u16);
|
||||
const size_t optimize_map_size = CalculateOptimizedProcessOverheadSize(size);
|
||||
@ -417,7 +418,7 @@ size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr manage
|
||||
m_management_region = management;
|
||||
m_page_reference_counts.resize(
|
||||
Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize() / PageSize);
|
||||
ASSERT(Common::IsAligned(m_management_region, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(m_management_region), PageSize));
|
||||
|
||||
// Initialize the manager's KPageHeap.
|
||||
m_heap.Initialize(address, size, management + manager_size, page_heap_size);
|
||||
@ -425,15 +426,15 @@ size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr manage
|
||||
return total_management_size;
|
||||
}
|
||||
|
||||
void KMemoryManager::Impl::TrackUnoptimizedAllocation(PAddr block, size_t num_pages) {
|
||||
void KMemoryManager::Impl::TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void KMemoryManager::Impl::TrackOptimizedAllocation(PAddr block, size_t num_pages) {
|
||||
void KMemoryManager::Impl::TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
bool KMemoryManager::Impl::ProcessOptimizedAllocation(PAddr block, size_t num_pages,
|
||||
bool KMemoryManager::Impl::ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages,
|
||||
u8 fill_pattern) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -7,10 +7,10 @@
|
||||
#include <tuple>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_light_lock.h"
|
||||
#include "core/hle/kernel/k_memory_layout.h"
|
||||
#include "core/hle/kernel/k_page_heap.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Core {
|
||||
@ -50,21 +50,21 @@ public:
|
||||
|
||||
explicit KMemoryManager(Core::System& system);
|
||||
|
||||
void Initialize(VAddr management_region, size_t management_region_size);
|
||||
void Initialize(KVirtualAddress management_region, size_t management_region_size);
|
||||
|
||||
Result InitializeOptimizedMemory(u64 process_id, Pool pool);
|
||||
void FinalizeOptimizedMemory(u64 process_id, Pool pool);
|
||||
|
||||
PAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option);
|
||||
KPhysicalAddress AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option);
|
||||
Result AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 option);
|
||||
Result AllocateForProcess(KPageGroup* out, size_t num_pages, u32 option, u64 process_id,
|
||||
u8 fill_pattern);
|
||||
|
||||
Pool GetPool(PAddr address) const {
|
||||
Pool GetPool(KPhysicalAddress address) const {
|
||||
return this->GetManager(address).GetPool();
|
||||
}
|
||||
|
||||
void Open(PAddr address, size_t num_pages) {
|
||||
void Open(KPhysicalAddress address, size_t num_pages) {
|
||||
// Repeatedly open references until we've done so for all pages.
|
||||
while (num_pages) {
|
||||
auto& manager = this->GetManager(address);
|
||||
@ -80,7 +80,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void OpenFirst(PAddr address, size_t num_pages) {
|
||||
void OpenFirst(KPhysicalAddress address, size_t num_pages) {
|
||||
// Repeatedly open references until we've done so for all pages.
|
||||
while (num_pages) {
|
||||
auto& manager = this->GetManager(address);
|
||||
@ -96,7 +96,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void Close(PAddr address, size_t num_pages) {
|
||||
void Close(KPhysicalAddress address, size_t num_pages) {
|
||||
// Repeatedly close references until we've done so for all pages.
|
||||
while (num_pages) {
|
||||
auto& manager = this->GetManager(address);
|
||||
@ -199,16 +199,16 @@ private:
|
||||
public:
|
||||
Impl() = default;
|
||||
|
||||
size_t Initialize(PAddr address, size_t size, VAddr management, VAddr management_end,
|
||||
Pool p);
|
||||
size_t Initialize(KPhysicalAddress address, size_t size, KVirtualAddress management,
|
||||
KVirtualAddress management_end, Pool p);
|
||||
|
||||
PAddr AllocateBlock(s32 index, bool random) {
|
||||
KPhysicalAddress AllocateBlock(s32 index, bool random) {
|
||||
return m_heap.AllocateBlock(index, random);
|
||||
}
|
||||
PAddr AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
|
||||
KPhysicalAddress AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
|
||||
return m_heap.AllocateAligned(index, num_pages, align_pages);
|
||||
}
|
||||
void Free(PAddr addr, size_t num_pages) {
|
||||
void Free(KPhysicalAddress addr, size_t num_pages) {
|
||||
m_heap.Free(addr, num_pages);
|
||||
}
|
||||
|
||||
@ -220,10 +220,10 @@ private:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void TrackUnoptimizedAllocation(PAddr block, size_t num_pages);
|
||||
void TrackOptimizedAllocation(PAddr block, size_t num_pages);
|
||||
void TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages);
|
||||
void TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages);
|
||||
|
||||
bool ProcessOptimizedAllocation(PAddr block, size_t num_pages, u8 fill_pattern);
|
||||
bool ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages, u8 fill_pattern);
|
||||
|
||||
constexpr Pool GetPool() const {
|
||||
return m_pool;
|
||||
@ -231,7 +231,7 @@ private:
|
||||
constexpr size_t GetSize() const {
|
||||
return m_heap.GetSize();
|
||||
}
|
||||
constexpr PAddr GetEndAddress() const {
|
||||
constexpr KPhysicalAddress GetEndAddress() const {
|
||||
return m_heap.GetEndAddress();
|
||||
}
|
||||
|
||||
@ -243,10 +243,10 @@ private:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
constexpr size_t GetPageOffset(PAddr address) const {
|
||||
constexpr size_t GetPageOffset(KPhysicalAddress address) const {
|
||||
return m_heap.GetPageOffset(address);
|
||||
}
|
||||
constexpr size_t GetPageOffsetToEnd(PAddr address) const {
|
||||
constexpr size_t GetPageOffsetToEnd(KPhysicalAddress address) const {
|
||||
return m_heap.GetPageOffsetToEnd(address);
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ private:
|
||||
return m_prev;
|
||||
}
|
||||
|
||||
void OpenFirst(PAddr address, size_t num_pages) {
|
||||
void OpenFirst(KPhysicalAddress address, size_t num_pages) {
|
||||
size_t index = this->GetPageOffset(address);
|
||||
const size_t end = index + num_pages;
|
||||
while (index < end) {
|
||||
@ -274,7 +274,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void Open(PAddr address, size_t num_pages) {
|
||||
void Open(KPhysicalAddress address, size_t num_pages) {
|
||||
size_t index = this->GetPageOffset(address);
|
||||
const size_t end = index + num_pages;
|
||||
while (index < end) {
|
||||
@ -285,7 +285,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void Close(PAddr address, size_t num_pages) {
|
||||
void Close(KPhysicalAddress address, size_t num_pages) {
|
||||
size_t index = this->GetPageOffset(address);
|
||||
const size_t end = index + num_pages;
|
||||
|
||||
@ -323,18 +323,18 @@ private:
|
||||
|
||||
KPageHeap m_heap;
|
||||
std::vector<RefCount> m_page_reference_counts;
|
||||
VAddr m_management_region{};
|
||||
KVirtualAddress m_management_region{};
|
||||
Pool m_pool{};
|
||||
Impl* m_next{};
|
||||
Impl* m_prev{};
|
||||
};
|
||||
|
||||
private:
|
||||
Impl& GetManager(PAddr address) {
|
||||
Impl& GetManager(KPhysicalAddress address) {
|
||||
return m_managers[m_memory_layout.GetPhysicalLinearRegion(address).GetAttributes()];
|
||||
}
|
||||
|
||||
const Impl& GetManager(PAddr address) const {
|
||||
const Impl& GetManager(KPhysicalAddress address) const {
|
||||
return m_managers[m_memory_layout.GetPhysicalLinearRegion(address).GetAttributes()];
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/intrusive_red_black_tree.h"
|
||||
#include "core/hle/kernel/k_memory_region_type.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@ -243,10 +243,10 @@ public:
|
||||
void InsertDirectly(u64 address, u64 last_address, u32 attr = 0, u32 type_id = 0);
|
||||
bool Insert(u64 address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
|
||||
|
||||
VAddr GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
|
||||
KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
|
||||
|
||||
VAddr GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id,
|
||||
size_t guard_size) {
|
||||
KVirtualAddress GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id,
|
||||
size_t guard_size) {
|
||||
return this->GetRandomAlignedRegion(size + 2 * guard_size, alignment, type_id) + guard_size;
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
KPageBuffer* KPageBuffer::FromPhysicalAddress(Core::System& system, PAddr phys_addr) {
|
||||
ASSERT(Common::IsAligned(phys_addr, PageSize));
|
||||
KPageBuffer* KPageBuffer::FromPhysicalAddress(Core::System& system, KPhysicalAddress phys_addr) {
|
||||
ASSERT(Common::IsAligned(GetInteger(phys_addr), PageSize));
|
||||
return system.DeviceMemory().GetPointer<KPageBuffer>(phys_addr);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
explicit KPageBuffer(KernelCore&) {}
|
||||
KPageBuffer() = default;
|
||||
|
||||
static KPageBuffer* FromPhysicalAddress(Core::System& system, PAddr phys_addr);
|
||||
static KPageBuffer* FromPhysicalAddress(Core::System& system, KPhysicalAddress phys_addr);
|
||||
|
||||
private:
|
||||
alignas(PageSize) std::array<u8, PageSize> m_buffer{};
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
constexpr explicit KBlockInfo() : m_next(nullptr) {}
|
||||
|
||||
constexpr void Initialize(KPhysicalAddress addr, size_t np) {
|
||||
ASSERT(Common::IsAligned(addr, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
|
||||
ASSERT(static_cast<u32>(np) == np);
|
||||
|
||||
m_page_index = static_cast<u32>(addr / PageSize);
|
||||
|
@ -6,14 +6,14 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
void KPageHeap::Initialize(PAddr address, size_t size, VAddr management_address,
|
||||
size_t management_size, const size_t* block_shifts,
|
||||
size_t num_block_shifts) {
|
||||
void KPageHeap::Initialize(KPhysicalAddress address, size_t size,
|
||||
KVirtualAddress management_address, size_t management_size,
|
||||
const size_t* block_shifts, size_t num_block_shifts) {
|
||||
// Check our assumptions.
|
||||
ASSERT(Common::IsAligned(address, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(address), PageSize));
|
||||
ASSERT(Common::IsAligned(size, PageSize));
|
||||
ASSERT(0 < num_block_shifts && num_block_shifts <= NumMemoryBlockPageShifts);
|
||||
const VAddr management_end = management_address + management_size;
|
||||
const KVirtualAddress management_end = management_address + management_size;
|
||||
|
||||
// Set our members.
|
||||
m_heap_address = address;
|
||||
@ -31,7 +31,7 @@ void KPageHeap::Initialize(PAddr address, size_t size, VAddr management_address,
|
||||
}
|
||||
|
||||
// Ensure we didn't overextend our bounds.
|
||||
ASSERT(VAddr(cur_bitmap_storage) <= management_end);
|
||||
ASSERT(KVirtualAddress(cur_bitmap_storage) <= management_end);
|
||||
}
|
||||
|
||||
size_t KPageHeap::GetNumFreePages() const {
|
||||
@ -44,11 +44,11 @@ size_t KPageHeap::GetNumFreePages() const {
|
||||
return num_free;
|
||||
}
|
||||
|
||||
PAddr KPageHeap::AllocateByLinearSearch(s32 index) {
|
||||
KPhysicalAddress KPageHeap::AllocateByLinearSearch(s32 index) {
|
||||
const size_t needed_size = m_blocks[index].GetSize();
|
||||
|
||||
for (s32 i = index; i < static_cast<s32>(m_num_blocks); i++) {
|
||||
if (const PAddr addr = m_blocks[i].PopBlock(false); addr != 0) {
|
||||
if (const KPhysicalAddress addr = m_blocks[i].PopBlock(false); addr != 0) {
|
||||
if (const size_t allocated_size = m_blocks[i].GetSize(); allocated_size > needed_size) {
|
||||
this->Free(addr + needed_size, (allocated_size - needed_size) / PageSize);
|
||||
}
|
||||
@ -59,7 +59,7 @@ PAddr KPageHeap::AllocateByLinearSearch(s32 index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_pages) {
|
||||
KPhysicalAddress KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_pages) {
|
||||
// Get the size and required alignment.
|
||||
const size_t needed_size = num_pages * PageSize;
|
||||
const size_t align_size = align_pages * PageSize;
|
||||
@ -110,7 +110,7 @@ PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_page
|
||||
}
|
||||
|
||||
// Pop a block from the index we selected.
|
||||
if (PAddr addr = m_blocks[index].PopBlock(true); addr != 0) {
|
||||
if (KPhysicalAddress addr = m_blocks[index].PopBlock(true); addr != 0) {
|
||||
// Determine how much size we have left over.
|
||||
if (const size_t leftover_size = m_blocks[index].GetSize() - needed_size;
|
||||
leftover_size > 0) {
|
||||
@ -141,13 +141,13 @@ PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_page
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KPageHeap::FreeBlock(PAddr block, s32 index) {
|
||||
void KPageHeap::FreeBlock(KPhysicalAddress block, s32 index) {
|
||||
do {
|
||||
block = m_blocks[index++].PushBlock(block);
|
||||
} while (block != 0);
|
||||
}
|
||||
|
||||
void KPageHeap::Free(PAddr addr, size_t num_pages) {
|
||||
void KPageHeap::Free(KPhysicalAddress addr, size_t num_pages) {
|
||||
// Freeing no pages is a no-op.
|
||||
if (num_pages == 0) {
|
||||
return;
|
||||
@ -155,16 +155,16 @@ void KPageHeap::Free(PAddr addr, size_t num_pages) {
|
||||
|
||||
// Find the largest block size that we can free, and free as many as possible.
|
||||
s32 big_index = static_cast<s32>(m_num_blocks) - 1;
|
||||
const PAddr start = addr;
|
||||
const PAddr end = addr + num_pages * PageSize;
|
||||
PAddr before_start = start;
|
||||
PAddr before_end = start;
|
||||
PAddr after_start = end;
|
||||
PAddr after_end = end;
|
||||
const KPhysicalAddress start = addr;
|
||||
const KPhysicalAddress end = addr + num_pages * PageSize;
|
||||
KPhysicalAddress before_start = start;
|
||||
KPhysicalAddress before_end = start;
|
||||
KPhysicalAddress after_start = end;
|
||||
KPhysicalAddress after_end = end;
|
||||
while (big_index >= 0) {
|
||||
const size_t block_size = m_blocks[big_index].GetSize();
|
||||
const PAddr big_start = Common::AlignUp(start, block_size);
|
||||
const PAddr big_end = Common::AlignDown(end, block_size);
|
||||
const KPhysicalAddress big_start = Common::AlignUp(GetInteger(start), block_size);
|
||||
const KPhysicalAddress big_end = Common::AlignDown(GetInteger(end), block_size);
|
||||
if (big_start < big_end) {
|
||||
// Free as many big blocks as we can.
|
||||
for (auto block = big_start; block < big_end; block += block_size) {
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_page_bitmap.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/memory_types.h"
|
||||
|
||||
namespace Kernel {
|
||||
@ -18,24 +18,24 @@ class KPageHeap {
|
||||
public:
|
||||
KPageHeap() = default;
|
||||
|
||||
constexpr PAddr GetAddress() const {
|
||||
constexpr KPhysicalAddress GetAddress() const {
|
||||
return m_heap_address;
|
||||
}
|
||||
constexpr size_t GetSize() const {
|
||||
return m_heap_size;
|
||||
}
|
||||
constexpr PAddr GetEndAddress() const {
|
||||
constexpr KPhysicalAddress GetEndAddress() const {
|
||||
return this->GetAddress() + this->GetSize();
|
||||
}
|
||||
constexpr size_t GetPageOffset(PAddr block) const {
|
||||
constexpr size_t GetPageOffset(KPhysicalAddress block) const {
|
||||
return (block - this->GetAddress()) / PageSize;
|
||||
}
|
||||
constexpr size_t GetPageOffsetToEnd(PAddr block) const {
|
||||
constexpr size_t GetPageOffsetToEnd(KPhysicalAddress block) const {
|
||||
return (this->GetEndAddress() - block) / PageSize;
|
||||
}
|
||||
|
||||
void Initialize(PAddr heap_address, size_t heap_size, VAddr management_address,
|
||||
size_t management_size) {
|
||||
void Initialize(KPhysicalAddress heap_address, size_t heap_size,
|
||||
KVirtualAddress management_address, size_t management_size) {
|
||||
return this->Initialize(heap_address, heap_size, management_address, management_size,
|
||||
MemoryBlockPageShifts.data(), NumMemoryBlockPageShifts);
|
||||
}
|
||||
@ -53,7 +53,7 @@ public:
|
||||
m_initial_used_size = m_heap_size - free_size - reserved_size;
|
||||
}
|
||||
|
||||
PAddr AllocateBlock(s32 index, bool random) {
|
||||
KPhysicalAddress AllocateBlock(s32 index, bool random) {
|
||||
if (random) {
|
||||
const size_t block_pages = m_blocks[index].GetNumPages();
|
||||
return this->AllocateByRandom(index, block_pages, block_pages);
|
||||
@ -62,12 +62,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
PAddr AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
|
||||
KPhysicalAddress AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
|
||||
// TODO: linear search support?
|
||||
return this->AllocateByRandom(index, num_pages, align_pages);
|
||||
}
|
||||
|
||||
void Free(PAddr addr, size_t num_pages);
|
||||
void Free(KPhysicalAddress addr, size_t num_pages);
|
||||
|
||||
static size_t CalculateManagementOverheadSize(size_t region_size) {
|
||||
return CalculateManagementOverheadSize(region_size, MemoryBlockPageShifts.data(),
|
||||
@ -125,24 +125,25 @@ private:
|
||||
return this->GetNumFreeBlocks() * this->GetNumPages();
|
||||
}
|
||||
|
||||
u64* Initialize(PAddr addr, size_t size, size_t bs, size_t nbs, u64* bit_storage) {
|
||||
u64* Initialize(KPhysicalAddress addr, size_t size, size_t bs, size_t nbs,
|
||||
u64* bit_storage) {
|
||||
// Set shifts.
|
||||
m_block_shift = bs;
|
||||
m_next_block_shift = nbs;
|
||||
|
||||
// Align up the address.
|
||||
PAddr end = addr + size;
|
||||
KPhysicalAddress end = addr + size;
|
||||
const size_t align = (m_next_block_shift != 0) ? (u64(1) << m_next_block_shift)
|
||||
: (u64(1) << m_block_shift);
|
||||
addr = Common::AlignDown(addr, align);
|
||||
end = Common::AlignUp(end, align);
|
||||
addr = Common::AlignDown(GetInteger(addr), align);
|
||||
end = Common::AlignUp(GetInteger(end), align);
|
||||
|
||||
m_heap_address = addr;
|
||||
m_end_offset = (end - addr) / (u64(1) << m_block_shift);
|
||||
return m_bitmap.Initialize(bit_storage, m_end_offset);
|
||||
}
|
||||
|
||||
PAddr PushBlock(PAddr address) {
|
||||
KPhysicalAddress PushBlock(KPhysicalAddress address) {
|
||||
// Set the bit for the free block.
|
||||
size_t offset = (address - m_heap_address) >> this->GetShift();
|
||||
m_bitmap.SetBit(offset);
|
||||
@ -161,7 +162,7 @@ private:
|
||||
return {};
|
||||
}
|
||||
|
||||
PAddr PopBlock(bool random) {
|
||||
KPhysicalAddress PopBlock(bool random) {
|
||||
// Find a free block.
|
||||
s64 soffset = m_bitmap.FindFreeBlock(random);
|
||||
if (soffset < 0) {
|
||||
@ -187,18 +188,19 @@ private:
|
||||
|
||||
private:
|
||||
KPageBitmap m_bitmap;
|
||||
PAddr m_heap_address{};
|
||||
KPhysicalAddress m_heap_address{};
|
||||
uintptr_t m_end_offset{};
|
||||
size_t m_block_shift{};
|
||||
size_t m_next_block_shift{};
|
||||
};
|
||||
|
||||
private:
|
||||
void Initialize(PAddr heap_address, size_t heap_size, VAddr management_address,
|
||||
size_t management_size, const size_t* block_shifts, size_t num_block_shifts);
|
||||
void Initialize(KPhysicalAddress heap_address, size_t heap_size,
|
||||
KVirtualAddress management_address, size_t management_size,
|
||||
const size_t* block_shifts, size_t num_block_shifts);
|
||||
size_t GetNumFreePages() const;
|
||||
|
||||
void FreeBlock(PAddr block, s32 index);
|
||||
void FreeBlock(KPhysicalAddress block, s32 index);
|
||||
|
||||
static constexpr size_t NumMemoryBlockPageShifts{7};
|
||||
static constexpr std::array<size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{
|
||||
@ -206,14 +208,14 @@ private:
|
||||
};
|
||||
|
||||
private:
|
||||
PAddr AllocateByLinearSearch(s32 index);
|
||||
PAddr AllocateByRandom(s32 index, size_t num_pages, size_t align_pages);
|
||||
KPhysicalAddress AllocateByLinearSearch(s32 index);
|
||||
KPhysicalAddress AllocateByRandom(s32 index, size_t num_pages, size_t align_pages);
|
||||
|
||||
static size_t CalculateManagementOverheadSize(size_t region_size, const size_t* block_shifts,
|
||||
size_t num_block_shifts);
|
||||
|
||||
private:
|
||||
PAddr m_heap_address{};
|
||||
KPhysicalAddress m_heap_address{};
|
||||
size_t m_heap_size{};
|
||||
size_t m_initial_used_size{};
|
||||
size_t m_num_blocks{};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,6 @@
|
||||
#include <memory>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/page_table.h"
|
||||
#include "core/file_sys/program_metadata.h"
|
||||
#include "core/hle/kernel/k_dynamic_resource_manager.h"
|
||||
@ -15,6 +14,7 @@
|
||||
#include "core/hle/kernel/k_memory_block_manager.h"
|
||||
#include "core/hle/kernel/k_memory_layout.h"
|
||||
#include "core/hle/kernel/k_memory_manager.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
@ -65,45 +65,47 @@ public:
|
||||
|
||||
Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
|
||||
bool enable_das_merge, bool from_back, KMemoryManager::Pool pool,
|
||||
VAddr code_addr, size_t code_size, KSystemResource* system_resource,
|
||||
KResourceLimit* resource_limit);
|
||||
KProcessAddress code_addr, size_t code_size,
|
||||
KSystemResource* system_resource, KResourceLimit* resource_limit);
|
||||
|
||||
void Finalize();
|
||||
|
||||
Result MapProcessCode(VAddr addr, size_t pages_count, KMemoryState state,
|
||||
Result MapProcessCode(KProcessAddress addr, size_t pages_count, KMemoryState state,
|
||||
KMemoryPermission perm);
|
||||
Result MapCodeMemory(VAddr dst_address, VAddr src_address, size_t size);
|
||||
Result UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t size,
|
||||
Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
|
||||
Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size,
|
||||
ICacheInvalidationStrategy icache_invalidation_strategy);
|
||||
Result UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& src_page_table,
|
||||
VAddr src_addr);
|
||||
Result MapPhysicalMemory(VAddr addr, size_t size);
|
||||
Result UnmapPhysicalMemory(VAddr addr, size_t size);
|
||||
Result MapMemory(VAddr dst_addr, VAddr src_addr, size_t size);
|
||||
Result UnmapMemory(VAddr dst_addr, VAddr src_addr, size_t size);
|
||||
Result SetProcessMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission svc_perm);
|
||||
KMemoryInfo QueryInfo(VAddr addr);
|
||||
Result SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission perm);
|
||||
Result SetMemoryAttribute(VAddr addr, size_t size, u32 mask, u32 attr);
|
||||
Result UnmapProcessMemory(KProcessAddress dst_addr, size_t size, KPageTable& src_page_table,
|
||||
KProcessAddress src_addr);
|
||||
Result MapPhysicalMemory(KProcessAddress addr, size_t size);
|
||||
Result UnmapPhysicalMemory(KProcessAddress addr, size_t size);
|
||||
Result MapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size);
|
||||
Result UnmapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size);
|
||||
Result SetProcessMemoryPermission(KProcessAddress addr, size_t size,
|
||||
Svc::MemoryPermission svc_perm);
|
||||
KMemoryInfo QueryInfo(KProcessAddress addr);
|
||||
Result SetMemoryPermission(KProcessAddress addr, size_t size, Svc::MemoryPermission perm);
|
||||
Result SetMemoryAttribute(KProcessAddress addr, size_t size, u32 mask, u32 attr);
|
||||
Result SetMaxHeapSize(size_t size);
|
||||
Result SetHeapSize(VAddr* out, size_t size);
|
||||
Result LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, size_t size,
|
||||
Result SetHeapSize(u64* out, size_t size);
|
||||
Result LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address, size_t size,
|
||||
KMemoryPermission perm, bool is_aligned, bool check_heap);
|
||||
Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bool check_heap);
|
||||
Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap);
|
||||
|
||||
Result UnlockForDeviceAddressSpace(VAddr addr, size_t size);
|
||||
Result UnlockForDeviceAddressSpace(KProcessAddress addr, size_t size);
|
||||
|
||||
Result LockForIpcUserBuffer(PAddr* out, VAddr address, size_t size);
|
||||
Result UnlockForIpcUserBuffer(VAddr address, size_t size);
|
||||
Result LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address, size_t size);
|
||||
Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size);
|
||||
|
||||
Result SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr, KPageTable& src_page_table,
|
||||
KMemoryPermission test_perm, KMemoryState dst_state, bool send);
|
||||
Result CleanupForIpcServer(VAddr address, size_t size, KMemoryState dst_state);
|
||||
Result CleanupForIpcClient(VAddr address, size_t size, KMemoryState dst_state);
|
||||
Result SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr,
|
||||
KPageTable& src_page_table, KMemoryPermission test_perm,
|
||||
KMemoryState dst_state, bool send);
|
||||
Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state);
|
||||
Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state);
|
||||
|
||||
Result LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size);
|
||||
Result UnlockForCodeMemory(VAddr addr, size_t size, const KPageGroup& pg);
|
||||
Result MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages,
|
||||
Result LockForCodeMemory(KPageGroup* out, KProcessAddress addr, size_t size);
|
||||
Result UnlockForCodeMemory(KProcessAddress addr, size_t size, const KPageGroup& pg);
|
||||
Result MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages,
|
||||
KMemoryState state_mask, KMemoryState state,
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr);
|
||||
@ -120,7 +122,7 @@ public:
|
||||
return m_block_info_manager;
|
||||
}
|
||||
|
||||
bool CanContain(VAddr addr, size_t size, KMemoryState state) const;
|
||||
bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const;
|
||||
|
||||
Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
|
||||
KPhysicalAddress phys_addr, KProcessAddress region_start,
|
||||
@ -173,8 +175,8 @@ protected:
|
||||
m_root = n;
|
||||
}
|
||||
|
||||
void Push(Core::Memory::Memory& memory, VAddr addr) {
|
||||
this->Push(memory.GetPointer<Node>(addr));
|
||||
void Push(Core::Memory::Memory& memory, KVirtualAddress addr) {
|
||||
this->Push(memory.GetPointer<Node>(GetInteger(addr)));
|
||||
}
|
||||
|
||||
Node* Peek() const {
|
||||
@ -212,27 +214,28 @@ private:
|
||||
Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
|
||||
KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start,
|
||||
size_t region_num_pages, KMemoryState state, KMemoryPermission perm);
|
||||
bool IsRegionContiguous(VAddr addr, u64 size) const;
|
||||
void AddRegionToPages(VAddr start, size_t num_pages, KPageGroup& page_linked_list);
|
||||
KMemoryInfo QueryInfoImpl(VAddr addr);
|
||||
VAddr AllocateVirtualMemory(VAddr start, size_t region_num_pages, u64 needed_num_pages,
|
||||
size_t align);
|
||||
Result Operate(VAddr addr, size_t num_pages, const KPageGroup& page_group,
|
||||
bool IsRegionContiguous(KProcessAddress addr, u64 size) const;
|
||||
void AddRegionToPages(KProcessAddress start, size_t num_pages, KPageGroup& page_linked_list);
|
||||
KMemoryInfo QueryInfoImpl(KProcessAddress addr);
|
||||
KProcessAddress AllocateVirtualMemory(KProcessAddress start, size_t region_num_pages,
|
||||
u64 needed_num_pages, size_t align);
|
||||
Result Operate(KProcessAddress addr, size_t num_pages, const KPageGroup& page_group,
|
||||
OperationType operation);
|
||||
Result Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, OperationType operation,
|
||||
PAddr map_addr = 0);
|
||||
Result Operate(KProcessAddress addr, size_t num_pages, KMemoryPermission perm,
|
||||
OperationType operation, KPhysicalAddress map_addr = 0);
|
||||
void FinalizeUpdate(PageLinkedList* page_list);
|
||||
VAddr GetRegionAddress(KMemoryState state) const;
|
||||
KProcessAddress GetRegionAddress(KMemoryState state) const;
|
||||
size_t GetRegionSize(KMemoryState state) const;
|
||||
|
||||
VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
|
||||
size_t alignment, size_t offset, size_t guard_pages);
|
||||
KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
|
||||
size_t num_pages, size_t alignment, size_t offset,
|
||||
size_t guard_pages);
|
||||
|
||||
Result CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr addr, size_t size,
|
||||
Result CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
|
||||
KMemoryState state_mask, KMemoryState state,
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
|
||||
Result CheckMemoryStateContiguous(VAddr addr, size_t size, KMemoryState state_mask,
|
||||
Result CheckMemoryStateContiguous(KProcessAddress addr, size_t size, KMemoryState state_mask,
|
||||
KMemoryState state, KMemoryPermission perm_mask,
|
||||
KMemoryPermission perm, KMemoryAttribute attr_mask,
|
||||
KMemoryAttribute attr) const {
|
||||
@ -244,12 +247,12 @@ private:
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
|
||||
Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
|
||||
KMemoryAttribute* out_attr, size_t* out_blocks_needed, VAddr addr,
|
||||
size_t size, KMemoryState state_mask, KMemoryState state,
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute* out_attr, size_t* out_blocks_needed,
|
||||
KProcessAddress addr, size_t size, KMemoryState state_mask,
|
||||
KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr,
|
||||
KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const;
|
||||
Result CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size,
|
||||
Result CheckMemoryState(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
|
||||
KMemoryState state_mask, KMemoryState state,
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr,
|
||||
@ -258,39 +261,40 @@ private:
|
||||
state_mask, state, perm_mask, perm, attr_mask, attr,
|
||||
ignore_attr));
|
||||
}
|
||||
Result CheckMemoryState(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state,
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
Result CheckMemoryState(KProcessAddress addr, size_t size, KMemoryState state_mask,
|
||||
KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr,
|
||||
KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
|
||||
R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm,
|
||||
attr_mask, attr, ignore_attr));
|
||||
}
|
||||
|
||||
Result LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size,
|
||||
KMemoryState state_mask, KMemoryState state,
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr,
|
||||
KMemoryPermission new_perm, KMemoryAttribute lock_attr);
|
||||
Result UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state,
|
||||
KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
Result LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_KPhysicalAddress,
|
||||
KProcessAddress addr, size_t size, KMemoryState state_mask,
|
||||
KMemoryState state, KMemoryPermission perm_mask,
|
||||
KMemoryPermission perm, KMemoryAttribute attr_mask,
|
||||
KMemoryAttribute attr, KMemoryPermission new_perm,
|
||||
KMemoryAttribute lock_attr);
|
||||
Result UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask,
|
||||
KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
|
||||
KMemoryAttribute attr_mask, KMemoryAttribute attr,
|
||||
KMemoryPermission new_perm, KMemoryAttribute lock_attr,
|
||||
const KPageGroup* pg);
|
||||
|
||||
Result MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages);
|
||||
bool IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_pages);
|
||||
Result MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages);
|
||||
bool IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr, size_t num_pages);
|
||||
|
||||
bool IsLockedByCurrentThread() const {
|
||||
return m_general_lock.IsLockedByCurrentThread();
|
||||
}
|
||||
|
||||
bool IsHeapPhysicalAddress(const KMemoryLayout& layout, PAddr phys_addr) {
|
||||
bool IsHeapPhysicalAddress(const KMemoryLayout& layout, KPhysicalAddress phys_addr) {
|
||||
ASSERT(this->IsLockedByCurrentThread());
|
||||
|
||||
return layout.IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr);
|
||||
}
|
||||
|
||||
bool GetPhysicalAddressLocked(PAddr* out, VAddr virt_addr) const {
|
||||
bool GetPhysicalAddressLocked(KPhysicalAddress* out, KProcessAddress virt_addr) const {
|
||||
ASSERT(this->IsLockedByCurrentThread());
|
||||
|
||||
*out = GetPhysicalAddr(virt_addr);
|
||||
@ -298,12 +302,13 @@ private:
|
||||
return *out != 0;
|
||||
}
|
||||
|
||||
Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed, VAddr address,
|
||||
size_t size, KMemoryPermission test_perm, KMemoryState dst_state);
|
||||
Result SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_addr,
|
||||
Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed,
|
||||
KProcessAddress address, size_t size, KMemoryPermission test_perm,
|
||||
KMemoryState dst_state);
|
||||
Result SetupForIpcServer(KProcessAddress* out_addr, size_t size, KProcessAddress src_addr,
|
||||
KMemoryPermission test_perm, KMemoryState dst_state,
|
||||
KPageTable& src_page_table, bool send);
|
||||
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, VAddr address,
|
||||
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, KProcessAddress address,
|
||||
size_t size, KMemoryPermission prot_perm);
|
||||
|
||||
Result AllocateAndMapPagesImpl(PageLinkedList* page_list, KProcessAddress address,
|
||||
@ -315,61 +320,61 @@ private:
|
||||
mutable KLightLock m_map_physical_memory_lock;
|
||||
|
||||
public:
|
||||
constexpr VAddr GetAddressSpaceStart() const {
|
||||
constexpr KProcessAddress GetAddressSpaceStart() const {
|
||||
return m_address_space_start;
|
||||
}
|
||||
constexpr VAddr GetAddressSpaceEnd() const {
|
||||
constexpr KProcessAddress GetAddressSpaceEnd() const {
|
||||
return m_address_space_end;
|
||||
}
|
||||
constexpr size_t GetAddressSpaceSize() const {
|
||||
return m_address_space_end - m_address_space_start;
|
||||
}
|
||||
constexpr VAddr GetHeapRegionStart() const {
|
||||
constexpr KProcessAddress GetHeapRegionStart() const {
|
||||
return m_heap_region_start;
|
||||
}
|
||||
constexpr VAddr GetHeapRegionEnd() const {
|
||||
constexpr KProcessAddress GetHeapRegionEnd() const {
|
||||
return m_heap_region_end;
|
||||
}
|
||||
constexpr size_t GetHeapRegionSize() const {
|
||||
return m_heap_region_end - m_heap_region_start;
|
||||
}
|
||||
constexpr VAddr GetAliasRegionStart() const {
|
||||
constexpr KProcessAddress GetAliasRegionStart() const {
|
||||
return m_alias_region_start;
|
||||
}
|
||||
constexpr VAddr GetAliasRegionEnd() const {
|
||||
constexpr KProcessAddress GetAliasRegionEnd() const {
|
||||
return m_alias_region_end;
|
||||
}
|
||||
constexpr size_t GetAliasRegionSize() const {
|
||||
return m_alias_region_end - m_alias_region_start;
|
||||
}
|
||||
constexpr VAddr GetStackRegionStart() const {
|
||||
constexpr KProcessAddress GetStackRegionStart() const {
|
||||
return m_stack_region_start;
|
||||
}
|
||||
constexpr VAddr GetStackRegionEnd() const {
|
||||
constexpr KProcessAddress GetStackRegionEnd() const {
|
||||
return m_stack_region_end;
|
||||
}
|
||||
constexpr size_t GetStackRegionSize() const {
|
||||
return m_stack_region_end - m_stack_region_start;
|
||||
}
|
||||
constexpr VAddr GetKernelMapRegionStart() const {
|
||||
constexpr KProcessAddress GetKernelMapRegionStart() const {
|
||||
return m_kernel_map_region_start;
|
||||
}
|
||||
constexpr VAddr GetKernelMapRegionEnd() const {
|
||||
constexpr KProcessAddress GetKernelMapRegionEnd() const {
|
||||
return m_kernel_map_region_end;
|
||||
}
|
||||
constexpr VAddr GetCodeRegionStart() const {
|
||||
constexpr KProcessAddress GetCodeRegionStart() const {
|
||||
return m_code_region_start;
|
||||
}
|
||||
constexpr VAddr GetCodeRegionEnd() const {
|
||||
constexpr KProcessAddress GetCodeRegionEnd() const {
|
||||
return m_code_region_end;
|
||||
}
|
||||
constexpr VAddr GetAliasCodeRegionStart() const {
|
||||
constexpr KProcessAddress GetAliasCodeRegionStart() const {
|
||||
return m_alias_code_region_start;
|
||||
}
|
||||
constexpr VAddr GetAliasCodeRegionEnd() const {
|
||||
constexpr KProcessAddress GetAliasCodeRegionEnd() const {
|
||||
return m_alias_code_region_end;
|
||||
}
|
||||
constexpr VAddr GetAliasCodeRegionSize() const {
|
||||
constexpr size_t GetAliasCodeRegionSize() const {
|
||||
return m_alias_code_region_end - m_alias_code_region_start;
|
||||
}
|
||||
size_t GetNormalMemorySize() {
|
||||
@ -382,25 +387,25 @@ public:
|
||||
constexpr size_t GetHeapSize() const {
|
||||
return m_current_heap_end - m_heap_region_start;
|
||||
}
|
||||
constexpr bool IsInsideAddressSpace(VAddr address, size_t size) const {
|
||||
constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const {
|
||||
return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1;
|
||||
}
|
||||
constexpr bool IsOutsideAliasRegion(VAddr address, size_t size) const {
|
||||
constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const {
|
||||
return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1;
|
||||
}
|
||||
constexpr bool IsOutsideStackRegion(VAddr address, size_t size) const {
|
||||
constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const {
|
||||
return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1;
|
||||
}
|
||||
constexpr bool IsInvalidRegion(VAddr address, size_t size) const {
|
||||
constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const {
|
||||
return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1;
|
||||
}
|
||||
constexpr bool IsInsideHeapRegion(VAddr address, size_t size) const {
|
||||
constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const {
|
||||
return address + size > m_heap_region_start && m_heap_region_end > address;
|
||||
}
|
||||
constexpr bool IsInsideAliasRegion(VAddr address, size_t size) const {
|
||||
constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const {
|
||||
return address + size > m_alias_region_start && m_alias_region_end > address;
|
||||
}
|
||||
constexpr bool IsOutsideASLRRegion(VAddr address, size_t size) const {
|
||||
constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const {
|
||||
if (IsInvalidRegion(address, size)) {
|
||||
return true;
|
||||
}
|
||||
@ -412,47 +417,53 @@ public:
|
||||
}
|
||||
return {};
|
||||
}
|
||||
constexpr bool IsInsideASLRRegion(VAddr address, size_t size) const {
|
||||
constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const {
|
||||
return !IsOutsideASLRRegion(address, size);
|
||||
}
|
||||
constexpr size_t GetNumGuardPages() const {
|
||||
return IsKernel() ? 1 : 4;
|
||||
}
|
||||
PAddr GetPhysicalAddr(VAddr addr) const {
|
||||
KPhysicalAddress GetPhysicalAddr(KProcessAddress addr) const {
|
||||
const auto backing_addr = m_page_table_impl->backing_addr[addr >> PageBits];
|
||||
ASSERT(backing_addr);
|
||||
return backing_addr + addr;
|
||||
return backing_addr + GetInteger(addr);
|
||||
}
|
||||
constexpr bool Contains(VAddr addr) const {
|
||||
constexpr bool Contains(KProcessAddress addr) const {
|
||||
return m_address_space_start <= addr && addr <= m_address_space_end - 1;
|
||||
}
|
||||
constexpr bool Contains(VAddr addr, size_t size) const {
|
||||
constexpr bool Contains(KProcessAddress addr, size_t size) const {
|
||||
return m_address_space_start <= addr && addr < addr + size &&
|
||||
addr + size - 1 <= m_address_space_end - 1;
|
||||
}
|
||||
|
||||
public:
|
||||
static VAddr GetLinearMappedVirtualAddress(const KMemoryLayout& layout, PAddr addr) {
|
||||
static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout,
|
||||
KPhysicalAddress addr) {
|
||||
return layout.GetLinearVirtualAddress(addr);
|
||||
}
|
||||
|
||||
static PAddr GetLinearMappedPhysicalAddress(const KMemoryLayout& layout, VAddr addr) {
|
||||
static KPhysicalAddress GetLinearMappedPhysicalAddress(const KMemoryLayout& layout,
|
||||
KVirtualAddress addr) {
|
||||
return layout.GetLinearPhysicalAddress(addr);
|
||||
}
|
||||
|
||||
static VAddr GetHeapVirtualAddress(const KMemoryLayout& layout, PAddr addr) {
|
||||
static KVirtualAddress GetHeapVirtualAddress(const KMemoryLayout& layout,
|
||||
KPhysicalAddress addr) {
|
||||
return GetLinearMappedVirtualAddress(layout, addr);
|
||||
}
|
||||
|
||||
static PAddr GetHeapPhysicalAddress(const KMemoryLayout& layout, VAddr addr) {
|
||||
static KPhysicalAddress GetHeapPhysicalAddress(const KMemoryLayout& layout,
|
||||
KVirtualAddress addr) {
|
||||
return GetLinearMappedPhysicalAddress(layout, addr);
|
||||
}
|
||||
|
||||
static VAddr GetPageTableVirtualAddress(const KMemoryLayout& layout, PAddr addr) {
|
||||
static KVirtualAddress GetPageTableVirtualAddress(const KMemoryLayout& layout,
|
||||
KPhysicalAddress addr) {
|
||||
return GetLinearMappedVirtualAddress(layout, addr);
|
||||
}
|
||||
|
||||
static PAddr GetPageTablePhysicalAddress(const KMemoryLayout& layout, VAddr addr) {
|
||||
static KPhysicalAddress GetPageTablePhysicalAddress(const KMemoryLayout& layout,
|
||||
KVirtualAddress addr) {
|
||||
return GetLinearMappedPhysicalAddress(layout, addr);
|
||||
}
|
||||
|
||||
@ -464,7 +475,7 @@ private:
|
||||
return m_enable_aslr;
|
||||
}
|
||||
|
||||
constexpr bool ContainsPages(VAddr addr, size_t num_pages) const {
|
||||
constexpr bool ContainsPages(KProcessAddress addr, size_t num_pages) const {
|
||||
return (m_address_space_start <= addr) &&
|
||||
(num_pages <= (m_address_space_end - m_address_space_start) / PageSize) &&
|
||||
(addr + num_pages * PageSize - 1 <= m_address_space_end - 1);
|
||||
@ -489,21 +500,21 @@ private:
|
||||
};
|
||||
|
||||
private:
|
||||
VAddr m_address_space_start{};
|
||||
VAddr m_address_space_end{};
|
||||
VAddr m_heap_region_start{};
|
||||
VAddr m_heap_region_end{};
|
||||
VAddr m_current_heap_end{};
|
||||
VAddr m_alias_region_start{};
|
||||
VAddr m_alias_region_end{};
|
||||
VAddr m_stack_region_start{};
|
||||
VAddr m_stack_region_end{};
|
||||
VAddr m_kernel_map_region_start{};
|
||||
VAddr m_kernel_map_region_end{};
|
||||
VAddr m_code_region_start{};
|
||||
VAddr m_code_region_end{};
|
||||
VAddr m_alias_code_region_start{};
|
||||
VAddr m_alias_code_region_end{};
|
||||
KProcessAddress m_address_space_start{};
|
||||
KProcessAddress m_address_space_end{};
|
||||
KProcessAddress m_heap_region_start{};
|
||||
KProcessAddress m_heap_region_end{};
|
||||
KProcessAddress m_current_heap_end{};
|
||||
KProcessAddress m_alias_region_start{};
|
||||
KProcessAddress m_alias_region_end{};
|
||||
KProcessAddress m_stack_region_start{};
|
||||
KProcessAddress m_stack_region_end{};
|
||||
KProcessAddress m_kernel_map_region_start{};
|
||||
KProcessAddress m_kernel_map_region_end{};
|
||||
KProcessAddress m_code_region_start{};
|
||||
KProcessAddress m_code_region_end{};
|
||||
KProcessAddress m_alias_code_region_start{};
|
||||
KProcessAddress m_alias_code_region_end{};
|
||||
|
||||
size_t m_max_heap_size{};
|
||||
size_t m_mapped_physical_memory_size{};
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_dynamic_resource_manager.h"
|
||||
#include "core/hle/kernel/k_page_table_slab_heap.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@ -26,23 +26,23 @@ public:
|
||||
BaseHeap::Initialize(page_allocator, pt_heap);
|
||||
}
|
||||
|
||||
VAddr Allocate() {
|
||||
return VAddr(BaseHeap::Allocate());
|
||||
KVirtualAddress Allocate() {
|
||||
return KVirtualAddress(BaseHeap::Allocate());
|
||||
}
|
||||
|
||||
RefCount GetRefCount(VAddr addr) const {
|
||||
RefCount GetRefCount(KVirtualAddress addr) const {
|
||||
return m_pt_heap->GetRefCount(addr);
|
||||
}
|
||||
|
||||
void Open(VAddr addr, int count) {
|
||||
void Open(KVirtualAddress addr, int count) {
|
||||
return m_pt_heap->Open(addr, count);
|
||||
}
|
||||
|
||||
bool Close(VAddr addr, int count) {
|
||||
bool Close(KVirtualAddress addr, int count) {
|
||||
return m_pt_heap->Close(addr, count);
|
||||
}
|
||||
|
||||
bool IsInPageTableHeap(VAddr addr) const {
|
||||
bool IsInPageTableHeap(KVirtualAddress addr) const {
|
||||
return m_pt_heap->IsInRange(addr);
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_dynamic_slab_heap.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
|
||||
namespace Kernel {
|
||||
@ -45,12 +45,12 @@ public:
|
||||
this->Initialize(rc);
|
||||
}
|
||||
|
||||
RefCount GetRefCount(VAddr addr) {
|
||||
RefCount GetRefCount(KVirtualAddress addr) {
|
||||
ASSERT(this->IsInRange(addr));
|
||||
return *this->GetRefCountPointer(addr);
|
||||
}
|
||||
|
||||
void Open(VAddr addr, int count) {
|
||||
void Open(KVirtualAddress addr, int count) {
|
||||
ASSERT(this->IsInRange(addr));
|
||||
|
||||
*this->GetRefCountPointer(addr) += static_cast<RefCount>(count);
|
||||
@ -58,7 +58,7 @@ public:
|
||||
ASSERT(this->GetRefCount(addr) > 0);
|
||||
}
|
||||
|
||||
bool Close(VAddr addr, int count) {
|
||||
bool Close(KVirtualAddress addr, int count) {
|
||||
ASSERT(this->IsInRange(addr));
|
||||
ASSERT(this->GetRefCount(addr) >= count);
|
||||
|
||||
@ -66,7 +66,7 @@ public:
|
||||
return this->GetRefCount(addr) == 0;
|
||||
}
|
||||
|
||||
bool IsInPageTableHeap(VAddr addr) const {
|
||||
bool IsInPageTableHeap(KVirtualAddress addr) const {
|
||||
return this->IsInRange(addr);
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
RefCount* GetRefCountPointer(VAddr addr) {
|
||||
RefCount* GetRefCountPointer(KVirtualAddress addr) {
|
||||
return m_ref_counts.data() + ((addr - this->GetAddress()) / PageSize);
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,9 @@ namespace {
|
||||
* @param owner_process The parent process for the main thread
|
||||
* @param priority The priority to give the main thread
|
||||
*/
|
||||
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, VAddr stack_top) {
|
||||
const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart();
|
||||
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
|
||||
KProcessAddress stack_top) {
|
||||
const KProcessAddress entry_point = owner_process.PageTable().GetCodeRegionStart();
|
||||
ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
|
||||
|
||||
KThread* thread = KThread::Create(system.Kernel());
|
||||
@ -219,7 +220,7 @@ void KProcess::UnpinThread(KThread* thread) {
|
||||
KScheduler::SetSchedulerUpdateNeeded(m_kernel);
|
||||
}
|
||||
|
||||
Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address,
|
||||
Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address,
|
||||
[[maybe_unused]] size_t size) {
|
||||
// Lock ourselves, to prevent concurrent access.
|
||||
KScopedLightLock lk(m_state_lock);
|
||||
@ -248,7 +249,7 @@ Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr ad
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address,
|
||||
void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address,
|
||||
[[maybe_unused]] size_t size) {
|
||||
// Lock ourselves, to prevent concurrent access.
|
||||
KScopedLightLock lk(m_state_lock);
|
||||
@ -399,8 +400,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
|
||||
|
||||
case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
|
||||
m_memory_usage_capacity =
|
||||
m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart() +
|
||||
m_page_table.GetAliasRegionEnd() - m_page_table.GetAliasRegionStart();
|
||||
(m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart()) +
|
||||
(m_page_table.GetAliasRegionEnd() - m_page_table.GetAliasRegionStart());
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -492,9 +493,9 @@ void KProcess::Finalize() {
|
||||
KSynchronizationObject::Finalize();
|
||||
}
|
||||
|
||||
Result KProcess::CreateThreadLocalRegion(VAddr* out) {
|
||||
Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
|
||||
KThreadLocalPage* tlp = nullptr;
|
||||
VAddr tlr = 0;
|
||||
KProcessAddress tlr = 0;
|
||||
|
||||
// See if we can get a region from a partially used TLP.
|
||||
{
|
||||
@ -543,7 +544,7 @@ Result KProcess::CreateThreadLocalRegion(VAddr* out) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
|
||||
Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
|
||||
KThreadLocalPage* page_to_free = nullptr;
|
||||
|
||||
// Release the region.
|
||||
@ -551,10 +552,10 @@ Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
|
||||
KScopedSchedulerLock sl{m_kernel};
|
||||
|
||||
// Try to find the page in the partially used list.
|
||||
auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(addr, PageSize));
|
||||
auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize));
|
||||
if (it == m_partially_used_tlp_tree.end()) {
|
||||
// If we don't find it, it has to be in the fully used list.
|
||||
it = m_fully_used_tlp_tree.find_key(Common::AlignDown(addr, PageSize));
|
||||
it = m_fully_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize));
|
||||
R_UNLESS(it != m_fully_used_tlp_tree.end(), ResultInvalidAddress);
|
||||
|
||||
// Release the region.
|
||||
@ -591,7 +592,7 @@ Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size,
|
||||
bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
|
||||
DebugWatchpointType type) {
|
||||
const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
|
||||
return wp.type == DebugWatchpointType::None;
|
||||
@ -605,7 +606,8 @@ bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size,
|
||||
watch->end_address = addr + size;
|
||||
watch->type = type;
|
||||
|
||||
for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) {
|
||||
for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
|
||||
page += PageSize) {
|
||||
m_debug_page_refcounts[page]++;
|
||||
system.Memory().MarkRegionDebug(page, PageSize, true);
|
||||
}
|
||||
@ -613,7 +615,7 @@ bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
|
||||
bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
|
||||
DebugWatchpointType type) {
|
||||
const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
|
||||
return wp.start_address == addr && wp.end_address == addr + size && wp.type == type;
|
||||
@ -627,7 +629,8 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
|
||||
watch->end_address = 0;
|
||||
watch->type = DebugWatchpointType::None;
|
||||
|
||||
for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) {
|
||||
for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
|
||||
page += PageSize) {
|
||||
m_debug_page_refcounts[page]--;
|
||||
if (!m_debug_page_refcounts[page]) {
|
||||
system.Memory().MarkRegionDebug(page, PageSize, false);
|
||||
@ -637,7 +640,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
|
||||
return true;
|
||||
}
|
||||
|
||||
void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) {
|
||||
void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
|
||||
const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
|
||||
Svc::MemoryPermission permission) {
|
||||
m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_address_arbiter.h"
|
||||
#include "core/hle/kernel/k_auto_object.h"
|
||||
#include "core/hle/kernel/k_condition_variable.h"
|
||||
@ -16,6 +15,7 @@
|
||||
#include "core/hle/kernel/k_page_table.h"
|
||||
#include "core/hle/kernel/k_synchronization_object.h"
|
||||
#include "core/hle/kernel/k_thread_local_page.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/k_worker_task.h"
|
||||
#include "core/hle/kernel/process_capability.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
@ -59,8 +59,8 @@ enum class DebugWatchpointType : u8 {
|
||||
DECLARE_ENUM_FLAG_OPERATORS(DebugWatchpointType);
|
||||
|
||||
struct DebugWatchpoint {
|
||||
VAddr start_address;
|
||||
VAddr end_address;
|
||||
KProcessAddress start_address;
|
||||
KProcessAddress end_address;
|
||||
DebugWatchpointType type;
|
||||
};
|
||||
|
||||
@ -135,11 +135,11 @@ public:
|
||||
return m_handle_table;
|
||||
}
|
||||
|
||||
Result SignalToAddress(VAddr address) {
|
||||
Result SignalToAddress(KProcessAddress address) {
|
||||
return m_condition_var.SignalToAddress(address);
|
||||
}
|
||||
|
||||
Result WaitForAddress(Handle handle, VAddr address, u32 tag) {
|
||||
Result WaitForAddress(Handle handle, KProcessAddress address, u32 tag) {
|
||||
return m_condition_var.WaitForAddress(handle, address, tag);
|
||||
}
|
||||
|
||||
@ -147,20 +147,21 @@ public:
|
||||
return m_condition_var.Signal(cv_key, count);
|
||||
}
|
||||
|
||||
Result WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) {
|
||||
Result WaitConditionVariable(KProcessAddress address, u64 cv_key, u32 tag, s64 ns) {
|
||||
R_RETURN(m_condition_var.Wait(address, cv_key, tag, ns));
|
||||
}
|
||||
|
||||
Result SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, s32 count) {
|
||||
Result SignalAddressArbiter(uint64_t address, Svc::SignalType signal_type, s32 value,
|
||||
s32 count) {
|
||||
R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count));
|
||||
}
|
||||
|
||||
Result WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value,
|
||||
Result WaitAddressArbiter(uint64_t address, Svc::ArbitrationType arb_type, s32 value,
|
||||
s64 timeout) {
|
||||
R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout));
|
||||
}
|
||||
|
||||
VAddr GetProcessLocalRegionAddress() const {
|
||||
KProcessAddress GetProcessLocalRegionAddress() const {
|
||||
return m_plr_address;
|
||||
}
|
||||
|
||||
@ -352,7 +353,7 @@ public:
|
||||
*/
|
||||
void PrepareForTermination();
|
||||
|
||||
void LoadModule(CodeSet code_set, VAddr base_addr);
|
||||
void LoadModule(CodeSet code_set, KProcessAddress base_addr);
|
||||
|
||||
bool IsInitialized() const override {
|
||||
return m_is_initialized;
|
||||
@ -380,26 +381,28 @@ public:
|
||||
return m_state_lock;
|
||||
}
|
||||
|
||||
Result AddSharedMemory(KSharedMemory* shmem, VAddr address, size_t size);
|
||||
void RemoveSharedMemory(KSharedMemory* shmem, VAddr address, size_t size);
|
||||
Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
|
||||
void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Thread-local storage management
|
||||
|
||||
// Marks the next available region as used and returns the address of the slot.
|
||||
[[nodiscard]] Result CreateThreadLocalRegion(VAddr* out);
|
||||
[[nodiscard]] Result CreateThreadLocalRegion(KProcessAddress* out);
|
||||
|
||||
// Frees a used TLS slot identified by the given address
|
||||
Result DeleteThreadLocalRegion(VAddr addr);
|
||||
Result DeleteThreadLocalRegion(KProcessAddress addr);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Debug watchpoint management
|
||||
|
||||
// Attempts to insert a watchpoint into a free slot. Returns false if none are available.
|
||||
bool InsertWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type);
|
||||
bool InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
|
||||
DebugWatchpointType type);
|
||||
|
||||
// Attempts to remove the watchpoint specified by the given parameters.
|
||||
bool RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type);
|
||||
bool RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
|
||||
DebugWatchpointType type);
|
||||
|
||||
const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const {
|
||||
return m_watchpoints;
|
||||
@ -457,7 +460,7 @@ private:
|
||||
/// Resource limit descriptor for this process
|
||||
KResourceLimit* m_resource_limit{};
|
||||
|
||||
VAddr m_system_resource_address{};
|
||||
KVirtualAddress m_system_resource_address{};
|
||||
|
||||
/// The ideal CPU core for this process, threads are scheduled on this core by default.
|
||||
u8 m_ideal_core = 0;
|
||||
@ -485,7 +488,7 @@ private:
|
||||
KConditionVariable m_condition_var;
|
||||
|
||||
/// Address indicating the location of the process' dedicated TLS region.
|
||||
VAddr m_plr_address = 0;
|
||||
KProcessAddress m_plr_address = 0;
|
||||
|
||||
/// Random values for svcGetInfo RandomEntropy
|
||||
std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};
|
||||
@ -497,7 +500,7 @@ private:
|
||||
std::list<KSharedMemoryInfo*> m_shared_memory_list;
|
||||
|
||||
/// Address of the top of the main thread's stack
|
||||
VAddr m_main_thread_stack_top{};
|
||||
KProcessAddress m_main_thread_stack_top{};
|
||||
|
||||
/// Size of the main thread's stack
|
||||
std::size_t m_main_thread_stack_size{};
|
||||
@ -527,7 +530,7 @@ private:
|
||||
std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_idle_counts{};
|
||||
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
|
||||
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
|
||||
std::map<VAddr, u64> m_debug_page_refcounts;
|
||||
std::map<KProcessAddress, u64> m_debug_page_refcounts;
|
||||
|
||||
KThread* m_exception_thread{};
|
||||
|
||||
|
@ -511,7 +511,7 @@ void KScheduler::Reload(KThread* thread) {
|
||||
auto& cpu_core = m_kernel.System().ArmInterface(m_core_id);
|
||||
cpu_core.LoadContext(thread->GetContext32());
|
||||
cpu_core.LoadContext(thread->GetContext64());
|
||||
cpu_core.SetTlsAddress(thread->GetTlsAddress());
|
||||
cpu_core.SetTlsAddress(GetInteger(thread->GetTlsAddress()));
|
||||
cpu_core.SetTPIDR_EL0(thread->GetTpidrEl0());
|
||||
cpu_core.LoadWatchpointArray(thread->GetOwnerProcess()->GetWatchpoints());
|
||||
cpu_core.ClearExclusiveState();
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, size_t size,
|
||||
KMemoryState state, size_t index) {
|
||||
Result KSessionRequest::SessionMappings::PushMap(KProcessAddress client, KProcessAddress server,
|
||||
size_t size, KMemoryState state, size_t index) {
|
||||
// At most 15 buffers of each type (4-bit descriptor counts).
|
||||
ASSERT(index < ((1ul << 4) - 1) * 3);
|
||||
|
||||
@ -33,20 +33,21 @@ Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, siz
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result KSessionRequest::SessionMappings::PushSend(VAddr client, VAddr server, size_t size,
|
||||
KMemoryState state) {
|
||||
Result KSessionRequest::SessionMappings::PushSend(KProcessAddress client, KProcessAddress server,
|
||||
size_t size, KMemoryState state) {
|
||||
ASSERT(m_num_recv == 0);
|
||||
ASSERT(m_num_exch == 0);
|
||||
R_RETURN(this->PushMap(client, server, size, state, m_num_send++));
|
||||
}
|
||||
|
||||
Result KSessionRequest::SessionMappings::PushReceive(VAddr client, VAddr server, size_t size,
|
||||
KMemoryState state) {
|
||||
Result KSessionRequest::SessionMappings::PushReceive(KProcessAddress client, KProcessAddress server,
|
||||
size_t size, KMemoryState state) {
|
||||
ASSERT(m_num_exch == 0);
|
||||
R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv++));
|
||||
}
|
||||
|
||||
Result KSessionRequest::SessionMappings::PushExchange(VAddr client, VAddr server, size_t size,
|
||||
Result KSessionRequest::SessionMappings::PushExchange(KProcessAddress client,
|
||||
KProcessAddress server, size_t size,
|
||||
KMemoryState state) {
|
||||
R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv + m_num_exch++));
|
||||
}
|
||||
|
@ -26,17 +26,17 @@ public:
|
||||
|
||||
class Mapping {
|
||||
public:
|
||||
constexpr void Set(VAddr c, VAddr s, size_t sz, KMemoryState st) {
|
||||
constexpr void Set(KProcessAddress c, KProcessAddress s, size_t sz, KMemoryState st) {
|
||||
m_client_address = c;
|
||||
m_server_address = s;
|
||||
m_size = sz;
|
||||
m_state = st;
|
||||
}
|
||||
|
||||
constexpr VAddr GetClientAddress() const {
|
||||
constexpr KProcessAddress GetClientAddress() const {
|
||||
return m_client_address;
|
||||
}
|
||||
constexpr VAddr GetServerAddress() const {
|
||||
constexpr KProcessAddress GetServerAddress() const {
|
||||
return m_server_address;
|
||||
}
|
||||
constexpr size_t GetSize() const {
|
||||
@ -47,8 +47,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
VAddr m_client_address{};
|
||||
VAddr m_server_address{};
|
||||
KProcessAddress m_client_address{};
|
||||
KProcessAddress m_server_address{};
|
||||
size_t m_size{};
|
||||
KMemoryState m_state{};
|
||||
};
|
||||
@ -69,14 +69,17 @@ public:
|
||||
return m_num_exch;
|
||||
}
|
||||
|
||||
Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state);
|
||||
Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state);
|
||||
Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state);
|
||||
Result PushSend(KProcessAddress client, KProcessAddress server, size_t size,
|
||||
KMemoryState state);
|
||||
Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size,
|
||||
KMemoryState state);
|
||||
Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size,
|
||||
KMemoryState state);
|
||||
|
||||
VAddr GetSendClientAddress(size_t i) const {
|
||||
KProcessAddress GetSendClientAddress(size_t i) const {
|
||||
return GetSendMapping(i).GetClientAddress();
|
||||
}
|
||||
VAddr GetSendServerAddress(size_t i) const {
|
||||
KProcessAddress GetSendServerAddress(size_t i) const {
|
||||
return GetSendMapping(i).GetServerAddress();
|
||||
}
|
||||
size_t GetSendSize(size_t i) const {
|
||||
@ -86,10 +89,10 @@ public:
|
||||
return GetSendMapping(i).GetMemoryState();
|
||||
}
|
||||
|
||||
VAddr GetReceiveClientAddress(size_t i) const {
|
||||
KProcessAddress GetReceiveClientAddress(size_t i) const {
|
||||
return GetReceiveMapping(i).GetClientAddress();
|
||||
}
|
||||
VAddr GetReceiveServerAddress(size_t i) const {
|
||||
KProcessAddress GetReceiveServerAddress(size_t i) const {
|
||||
return GetReceiveMapping(i).GetServerAddress();
|
||||
}
|
||||
size_t GetReceiveSize(size_t i) const {
|
||||
@ -99,10 +102,10 @@ public:
|
||||
return GetReceiveMapping(i).GetMemoryState();
|
||||
}
|
||||
|
||||
VAddr GetExchangeClientAddress(size_t i) const {
|
||||
KProcessAddress GetExchangeClientAddress(size_t i) const {
|
||||
return GetExchangeMapping(i).GetClientAddress();
|
||||
}
|
||||
VAddr GetExchangeServerAddress(size_t i) const {
|
||||
KProcessAddress GetExchangeServerAddress(size_t i) const {
|
||||
return GetExchangeMapping(i).GetServerAddress();
|
||||
}
|
||||
size_t GetExchangeSize(size_t i) const {
|
||||
@ -113,7 +116,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Result PushMap(VAddr client, VAddr server, size_t size, KMemoryState state, size_t index);
|
||||
Result PushMap(KProcessAddress client, KProcessAddress server, size_t size,
|
||||
KMemoryState state, size_t index);
|
||||
|
||||
const Mapping& GetSendMapping(size_t i) const {
|
||||
ASSERT(i < m_num_send);
|
||||
@ -227,22 +231,25 @@ public:
|
||||
return m_mappings.GetExchangeCount();
|
||||
}
|
||||
|
||||
Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state) {
|
||||
Result PushSend(KProcessAddress client, KProcessAddress server, size_t size,
|
||||
KMemoryState state) {
|
||||
return m_mappings.PushSend(client, server, size, state);
|
||||
}
|
||||
|
||||
Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state) {
|
||||
Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size,
|
||||
KMemoryState state) {
|
||||
return m_mappings.PushReceive(client, server, size, state);
|
||||
}
|
||||
|
||||
Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state) {
|
||||
Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size,
|
||||
KMemoryState state) {
|
||||
return m_mappings.PushExchange(client, server, size, state);
|
||||
}
|
||||
|
||||
VAddr GetSendClientAddress(size_t i) const {
|
||||
KProcessAddress GetSendClientAddress(size_t i) const {
|
||||
return m_mappings.GetSendClientAddress(i);
|
||||
}
|
||||
VAddr GetSendServerAddress(size_t i) const {
|
||||
KProcessAddress GetSendServerAddress(size_t i) const {
|
||||
return m_mappings.GetSendServerAddress(i);
|
||||
}
|
||||
size_t GetSendSize(size_t i) const {
|
||||
@ -252,10 +259,10 @@ public:
|
||||
return m_mappings.GetSendMemoryState(i);
|
||||
}
|
||||
|
||||
VAddr GetReceiveClientAddress(size_t i) const {
|
||||
KProcessAddress GetReceiveClientAddress(size_t i) const {
|
||||
return m_mappings.GetReceiveClientAddress(i);
|
||||
}
|
||||
VAddr GetReceiveServerAddress(size_t i) const {
|
||||
KProcessAddress GetReceiveServerAddress(size_t i) const {
|
||||
return m_mappings.GetReceiveServerAddress(i);
|
||||
}
|
||||
size_t GetReceiveSize(size_t i) const {
|
||||
@ -265,10 +272,10 @@ public:
|
||||
return m_mappings.GetReceiveMemoryState(i);
|
||||
}
|
||||
|
||||
VAddr GetExchangeClientAddress(size_t i) const {
|
||||
KProcessAddress GetExchangeClientAddress(size_t i) const {
|
||||
return m_mappings.GetExchangeClientAddress(i);
|
||||
}
|
||||
VAddr GetExchangeServerAddress(size_t i) const {
|
||||
KProcessAddress GetExchangeServerAddress(size_t i) const {
|
||||
return m_mappings.GetExchangeServerAddress(i);
|
||||
}
|
||||
size_t GetExchangeSize(size_t i) const {
|
||||
|
@ -76,7 +76,7 @@ void KSharedMemory::Finalize() {
|
||||
m_resource_limit->Close();
|
||||
}
|
||||
|
||||
Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size,
|
||||
Result KSharedMemory::Map(KProcess& target_process, KProcessAddress address, std::size_t map_size,
|
||||
Svc::MemoryPermission map_perm) {
|
||||
// Validate the size.
|
||||
R_UNLESS(m_size == map_size, ResultInvalidSize);
|
||||
@ -94,7 +94,8 @@ Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t m
|
||||
ConvertToKMemoryPermission(map_perm)));
|
||||
}
|
||||
|
||||
Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) {
|
||||
Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address,
|
||||
std::size_t unmap_size) {
|
||||
// Validate the size.
|
||||
R_UNLESS(m_size == unmap_size, ResultInvalidSize);
|
||||
|
||||
|
@ -6,11 +6,11 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/device_memory.h"
|
||||
#include "core/hle/kernel/k_memory_block.h"
|
||||
#include "core/hle/kernel/k_page_group.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
@ -37,7 +37,7 @@ public:
|
||||
* @param map_size Size of the shared memory block to map
|
||||
* @param permissions Memory block map permissions (specified by SVC field)
|
||||
*/
|
||||
Result Map(KProcess& target_process, VAddr address, std::size_t map_size,
|
||||
Result Map(KProcess& target_process, KProcessAddress address, std::size_t map_size,
|
||||
Svc::MemoryPermission permissions);
|
||||
|
||||
/**
|
||||
@ -46,7 +46,7 @@ public:
|
||||
* @param address Address in system memory to unmap shared memory block
|
||||
* @param unmap_size Size of the shared memory block to unmap
|
||||
*/
|
||||
Result Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size);
|
||||
Result Unmap(KProcess& target_process, KProcessAddress address, std::size_t unmap_size);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the shared memory block
|
||||
@ -79,7 +79,7 @@ private:
|
||||
std::optional<KPageGroup> m_page_group{};
|
||||
Svc::MemoryPermission m_owner_permission{};
|
||||
Svc::MemoryPermission m_user_permission{};
|
||||
PAddr m_physical_address{};
|
||||
KPhysicalAddress m_physical_address{};
|
||||
std::size_t m_size{};
|
||||
KResourceLimit* m_resource_limit{};
|
||||
bool m_is_initialized{};
|
||||
|
@ -130,7 +130,7 @@ private:
|
||||
KBlockInfoSlabHeap m_block_info_heap;
|
||||
KPageTableSlabHeap m_page_table_heap;
|
||||
KResourceLimit* m_resource_limit{};
|
||||
VAddr m_resource_address{};
|
||||
KVirtualAddress m_resource_address{};
|
||||
size_t m_resource_size{};
|
||||
};
|
||||
|
||||
|
@ -48,8 +48,8 @@ static void ResetThreadContext32(Kernel::KThread::ThreadContext32& context, u32
|
||||
context.fpscr = 0;
|
||||
}
|
||||
|
||||
static void ResetThreadContext64(Kernel::KThread::ThreadContext64& context, VAddr stack_top,
|
||||
VAddr entry_point, u64 arg) {
|
||||
static void ResetThreadContext64(Kernel::KThread::ThreadContext64& context, u64 stack_top,
|
||||
u64 entry_point, u64 arg) {
|
||||
context = {};
|
||||
context.cpu_registers[0] = arg;
|
||||
context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1;
|
||||
@ -100,8 +100,8 @@ KThread::KThread(KernelCore& kernel)
|
||||
: KAutoObjectWithSlabHeapAndContainer{kernel}, m_activity_pause_lock{kernel} {}
|
||||
KThread::~KThread() = default;
|
||||
|
||||
Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio,
|
||||
s32 virt_core, KProcess* owner, ThreadType type) {
|
||||
Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top,
|
||||
s32 prio, s32 virt_core, KProcess* owner, ThreadType type) {
|
||||
// Assert parameters are valid.
|
||||
ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) ||
|
||||
(Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority));
|
||||
@ -221,9 +221,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
|
||||
}
|
||||
|
||||
// Initialize thread context.
|
||||
ResetThreadContext64(m_thread_context_64, user_stack_top, func, arg);
|
||||
ResetThreadContext32(m_thread_context_32, static_cast<u32>(user_stack_top),
|
||||
static_cast<u32>(func), static_cast<u32>(arg));
|
||||
ResetThreadContext64(m_thread_context_64, GetInteger(user_stack_top), GetInteger(func), arg);
|
||||
ResetThreadContext32(m_thread_context_32, static_cast<u32>(GetInteger(user_stack_top)),
|
||||
static_cast<u32>(GetInteger(func)), static_cast<u32>(arg));
|
||||
|
||||
// Setup the stack parameters.
|
||||
StackParameters& sp = this->GetStackParameters();
|
||||
@ -249,8 +249,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
|
||||
}
|
||||
|
||||
Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
|
||||
VAddr user_stack_top, s32 prio, s32 core, KProcess* owner,
|
||||
ThreadType type, std::function<void()>&& init_func) {
|
||||
KProcessAddress user_stack_top, s32 prio, s32 core,
|
||||
KProcess* owner, ThreadType type,
|
||||
std::function<void()>&& init_func) {
|
||||
// Initialize the thread.
|
||||
R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type));
|
||||
|
||||
@ -288,8 +289,8 @@ Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thre
|
||||
}
|
||||
|
||||
Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
|
||||
uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core,
|
||||
KProcess* owner) {
|
||||
uintptr_t arg, KProcessAddress user_stack_top, s32 prio,
|
||||
s32 virt_core, KProcess* owner) {
|
||||
system.Kernel().GlobalSchedulerContext().AddThread(thread);
|
||||
R_RETURN(InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
|
||||
ThreadType::User, system.GetCpuManager().GetGuestThreadFunc()));
|
||||
@ -951,7 +952,7 @@ void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) {
|
||||
m_held_lock_info_list.push_front(*lock_info);
|
||||
}
|
||||
|
||||
KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(VAddr address_key,
|
||||
KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KProcessAddress address_key,
|
||||
bool is_kernel_address_key) {
|
||||
ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
|
||||
|
||||
@ -1087,7 +1088,8 @@ void KThread::RemoveWaiter(KThread* thread) {
|
||||
}
|
||||
}
|
||||
|
||||
KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key_) {
|
||||
KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key,
|
||||
bool is_kernel_address_key_) {
|
||||
ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
|
||||
|
||||
// Get the relevant lock info.
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/intrusive_red_black_tree.h"
|
||||
#include "common/spin_lock.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
@ -23,6 +22,7 @@
|
||||
#include "core/hle/kernel/k_spin_lock.h"
|
||||
#include "core/hle/kernel/k_synchronization_object.h"
|
||||
#include "core/hle/kernel/k_timer_task.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/k_worker_task.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
#include "core/hle/kernel/svc_common.h"
|
||||
@ -46,7 +46,7 @@ class KProcess;
|
||||
class KScheduler;
|
||||
class KThreadQueue;
|
||||
|
||||
using KThreadFunction = VAddr;
|
||||
using KThreadFunction = KProcessAddress;
|
||||
|
||||
enum class ThreadType : u32 {
|
||||
Main = 0,
|
||||
@ -230,9 +230,9 @@ public:
|
||||
|
||||
/*
|
||||
* Returns the Thread Local Storage address of the current thread
|
||||
* @returns VAddr of the thread's TLS
|
||||
* @returns Address of the thread's TLS
|
||||
*/
|
||||
VAddr GetTlsAddress() const {
|
||||
KProcessAddress GetTlsAddress() const {
|
||||
return m_tls_address;
|
||||
}
|
||||
|
||||
@ -419,8 +419,8 @@ public:
|
||||
KThreadFunction func, uintptr_t arg, s32 virt_core);
|
||||
|
||||
static Result InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
|
||||
uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core,
|
||||
KProcess* owner);
|
||||
uintptr_t arg, KProcessAddress user_stack_top, s32 prio,
|
||||
s32 virt_core, KProcess* owner);
|
||||
|
||||
static Result InitializeServiceThread(Core::System& system, KThread* thread,
|
||||
std::function<void()>&& thread_func, s32 prio,
|
||||
@ -565,15 +565,15 @@ public:
|
||||
|
||||
Result GetThreadContext3(std::vector<u8>& out);
|
||||
|
||||
KThread* RemoveUserWaiterByKey(bool* out_has_waiters, VAddr key) {
|
||||
KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) {
|
||||
return this->RemoveWaiterByKey(out_has_waiters, key, false);
|
||||
}
|
||||
|
||||
KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, VAddr key) {
|
||||
KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, KProcessAddress key) {
|
||||
return this->RemoveWaiterByKey(out_has_waiters, key, true);
|
||||
}
|
||||
|
||||
VAddr GetAddressKey() const {
|
||||
KProcessAddress GetAddressKey() const {
|
||||
return m_address_key;
|
||||
}
|
||||
|
||||
@ -591,14 +591,14 @@ public:
|
||||
// to cope with arbitrary host pointers making their way
|
||||
// into things.
|
||||
|
||||
void SetUserAddressKey(VAddr key, u32 val) {
|
||||
void SetUserAddressKey(KProcessAddress key, u32 val) {
|
||||
ASSERT(m_waiting_lock_info == nullptr);
|
||||
m_address_key = key;
|
||||
m_address_key_value = val;
|
||||
m_is_kernel_address_key = false;
|
||||
}
|
||||
|
||||
void SetKernelAddressKey(VAddr key) {
|
||||
void SetKernelAddressKey(KProcessAddress key) {
|
||||
ASSERT(m_waiting_lock_info == nullptr);
|
||||
m_address_key = key;
|
||||
m_is_kernel_address_key = true;
|
||||
@ -637,12 +637,13 @@ public:
|
||||
return m_argument;
|
||||
}
|
||||
|
||||
VAddr GetUserStackTop() const {
|
||||
KProcessAddress GetUserStackTop() const {
|
||||
return m_stack_top;
|
||||
}
|
||||
|
||||
private:
|
||||
KThread* RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key);
|
||||
KThread* RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key,
|
||||
bool is_kernel_address_key);
|
||||
|
||||
static constexpr size_t PriorityInheritanceCountMax = 10;
|
||||
union SyncObjectBuffer {
|
||||
@ -695,12 +696,13 @@ private:
|
||||
|
||||
void IncreaseBasePriority(s32 priority);
|
||||
|
||||
Result Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio,
|
||||
Result Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio,
|
||||
s32 virt_core, KProcess* owner, ThreadType type);
|
||||
|
||||
static Result InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
|
||||
VAddr user_stack_top, s32 prio, s32 core, KProcess* owner,
|
||||
ThreadType type, std::function<void()>&& init_func);
|
||||
KProcessAddress user_stack_top, s32 prio, s32 core,
|
||||
KProcess* owner, ThreadType type,
|
||||
std::function<void()>&& init_func);
|
||||
|
||||
// For core KThread implementation
|
||||
ThreadContext32 m_thread_context_32{};
|
||||
@ -749,7 +751,8 @@ public:
|
||||
public:
|
||||
explicit LockWithPriorityInheritanceInfo(KernelCore&) {}
|
||||
|
||||
static LockWithPriorityInheritanceInfo* Create(KernelCore& kernel, VAddr address_key,
|
||||
static LockWithPriorityInheritanceInfo* Create(KernelCore& kernel,
|
||||
KProcessAddress address_key,
|
||||
bool is_kernel_address_key) {
|
||||
// Create a new lock info.
|
||||
auto* new_lock = LockWithPriorityInheritanceInfo::Allocate(kernel);
|
||||
@ -797,7 +800,7 @@ public:
|
||||
return m_tree;
|
||||
}
|
||||
|
||||
VAddr GetAddressKey() const {
|
||||
KProcessAddress GetAddressKey() const {
|
||||
return m_address_key;
|
||||
}
|
||||
bool GetIsKernelAddressKey() const {
|
||||
@ -812,7 +815,7 @@ public:
|
||||
|
||||
private:
|
||||
LockWithPriorityInheritanceThreadTree m_tree{};
|
||||
VAddr m_address_key{};
|
||||
KProcessAddress m_address_key{};
|
||||
KThread* m_owner{};
|
||||
u32 m_waiter_count{};
|
||||
bool m_is_kernel_address_key{};
|
||||
@ -827,7 +830,8 @@ public:
|
||||
}
|
||||
|
||||
void AddHeldLock(LockWithPriorityInheritanceInfo* lock_info);
|
||||
LockWithPriorityInheritanceInfo* FindHeldLock(VAddr address_key, bool is_kernel_address_key);
|
||||
LockWithPriorityInheritanceInfo* FindHeldLock(KProcessAddress address_key,
|
||||
bool is_kernel_address_key);
|
||||
|
||||
private:
|
||||
using LockWithPriorityInheritanceInfoList =
|
||||
@ -839,11 +843,11 @@ private:
|
||||
KAffinityMask m_physical_affinity_mask{};
|
||||
u64 m_thread_id{};
|
||||
std::atomic<s64> m_cpu_time{};
|
||||
VAddr m_address_key{};
|
||||
KProcessAddress m_address_key{};
|
||||
KProcess* m_parent{};
|
||||
VAddr m_kernel_stack_top{};
|
||||
KVirtualAddress m_kernel_stack_top{};
|
||||
u32* m_light_ipc_data{};
|
||||
VAddr m_tls_address{};
|
||||
KProcessAddress m_tls_address{};
|
||||
KLightLock m_activity_pause_lock;
|
||||
s64 m_schedule_count{};
|
||||
s64 m_last_scheduled_tick{};
|
||||
@ -887,16 +891,16 @@ private:
|
||||
|
||||
// For debugging
|
||||
std::vector<KSynchronizationObject*> m_wait_objects_for_debugging{};
|
||||
VAddr m_mutex_wait_address_for_debugging{};
|
||||
KProcessAddress m_mutex_wait_address_for_debugging{};
|
||||
ThreadWaitReasonForDebugging m_wait_reason_for_debugging{};
|
||||
uintptr_t m_argument{};
|
||||
VAddr m_stack_top{};
|
||||
KProcessAddress m_stack_top{};
|
||||
|
||||
public:
|
||||
using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
|
||||
|
||||
void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, u64 cv_key,
|
||||
u32 value) {
|
||||
void SetConditionVariable(ConditionVariableThreadTree* tree, KProcessAddress address,
|
||||
u64 cv_key, u32 value) {
|
||||
ASSERT(m_waiting_lock_info == nullptr);
|
||||
m_condvar_tree = tree;
|
||||
m_condvar_key = cv_key;
|
||||
|
@ -37,7 +37,7 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
|
||||
|
||||
Result KThreadLocalPage::Finalize() {
|
||||
// Get the physical address of the page.
|
||||
const PAddr phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr);
|
||||
const KPhysicalAddress phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr);
|
||||
ASSERT(phys_addr);
|
||||
|
||||
// Unmap the page.
|
||||
@ -49,7 +49,7 @@ Result KThreadLocalPage::Finalize() {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
VAddr KThreadLocalPage::Reserve() {
|
||||
KProcessAddress KThreadLocalPage::Reserve() {
|
||||
for (size_t i = 0; i < m_is_region_free.size(); i++) {
|
||||
if (m_is_region_free[i]) {
|
||||
m_is_region_free[i] = false;
|
||||
@ -60,7 +60,7 @@ VAddr KThreadLocalPage::Reserve() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KThreadLocalPage::Release(VAddr addr) {
|
||||
void KThreadLocalPage::Release(KProcessAddress addr) {
|
||||
m_is_region_free[this->GetRegionIndex(addr)] = true;
|
||||
}
|
||||
|
||||
|
@ -27,19 +27,20 @@ public:
|
||||
static_assert(RegionsPerPage > 0);
|
||||
|
||||
public:
|
||||
constexpr explicit KThreadLocalPage(KernelCore&, VAddr addr = {}) : m_virt_addr(addr) {
|
||||
constexpr explicit KThreadLocalPage(KernelCore&, KProcessAddress addr = {})
|
||||
: m_virt_addr(addr) {
|
||||
m_is_region_free.fill(true);
|
||||
}
|
||||
|
||||
constexpr VAddr GetAddress() const {
|
||||
constexpr KProcessAddress GetAddress() const {
|
||||
return m_virt_addr;
|
||||
}
|
||||
|
||||
Result Initialize(KernelCore& kernel, KProcess* process);
|
||||
Result Finalize();
|
||||
|
||||
VAddr Reserve();
|
||||
void Release(VAddr addr);
|
||||
KProcessAddress Reserve();
|
||||
void Release(KProcessAddress addr);
|
||||
|
||||
bool IsAllUsed() const {
|
||||
return std::ranges::all_of(m_is_region_free.begin(), m_is_region_free.end(),
|
||||
@ -60,7 +61,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
using RedBlackKeyType = VAddr;
|
||||
using RedBlackKeyType = KProcessAddress;
|
||||
|
||||
static constexpr RedBlackKeyType GetRedBlackKey(const RedBlackKeyType& v) {
|
||||
return v;
|
||||
@ -72,8 +73,8 @@ public:
|
||||
template <typename T>
|
||||
requires(std::same_as<T, KThreadLocalPage> || std::same_as<T, RedBlackKeyType>)
|
||||
static constexpr int Compare(const T& lhs, const KThreadLocalPage& rhs) {
|
||||
const VAddr lval = GetRedBlackKey(lhs);
|
||||
const VAddr rval = GetRedBlackKey(rhs);
|
||||
const KProcessAddress lval = GetRedBlackKey(lhs);
|
||||
const KProcessAddress rval = GetRedBlackKey(rhs);
|
||||
|
||||
if (lval < rval) {
|
||||
return -1;
|
||||
@ -85,22 +86,22 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr VAddr GetRegionAddress(size_t i) const {
|
||||
constexpr KProcessAddress GetRegionAddress(size_t i) const {
|
||||
return this->GetAddress() + i * Svc::ThreadLocalRegionSize;
|
||||
}
|
||||
|
||||
constexpr bool Contains(VAddr addr) const {
|
||||
constexpr bool Contains(KProcessAddress addr) const {
|
||||
return this->GetAddress() <= addr && addr < this->GetAddress() + PageSize;
|
||||
}
|
||||
|
||||
constexpr size_t GetRegionIndex(VAddr addr) const {
|
||||
ASSERT(Common::IsAligned(addr, Svc::ThreadLocalRegionSize));
|
||||
constexpr size_t GetRegionIndex(KProcessAddress addr) const {
|
||||
ASSERT(Common::IsAligned(GetInteger(addr), Svc::ThreadLocalRegionSize));
|
||||
ASSERT(this->Contains(addr));
|
||||
return (addr - this->GetAddress()) / Svc::ThreadLocalRegionSize;
|
||||
}
|
||||
|
||||
private:
|
||||
VAddr m_virt_addr{};
|
||||
KProcessAddress m_virt_addr{};
|
||||
KProcess* m_owner{};
|
||||
KernelCore* m_kernel{};
|
||||
std::array<bool, RegionsPerPage> m_is_region_free{};
|
||||
|
@ -13,7 +13,7 @@ KTransferMemory::KTransferMemory(KernelCore& kernel)
|
||||
|
||||
KTransferMemory::~KTransferMemory() = default;
|
||||
|
||||
Result KTransferMemory::Initialize(VAddr address, std::size_t size,
|
||||
Result KTransferMemory::Initialize(KProcessAddress address, std::size_t size,
|
||||
Svc::MemoryPermission owner_perm) {
|
||||
// Set members.
|
||||
m_owner = GetCurrentProcessPointer(m_kernel);
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
explicit KTransferMemory(KernelCore& kernel);
|
||||
~KTransferMemory() override;
|
||||
|
||||
Result Initialize(VAddr address, std::size_t size, Svc::MemoryPermission owner_perm);
|
||||
Result Initialize(KProcessAddress address, std::size_t size, Svc::MemoryPermission owner_perm);
|
||||
|
||||
void Finalize() override;
|
||||
|
||||
@ -44,7 +44,7 @@ public:
|
||||
return m_owner;
|
||||
}
|
||||
|
||||
VAddr GetSourceAddress() const {
|
||||
KProcessAddress GetSourceAddress() const {
|
||||
return m_address;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
KProcess* m_owner{};
|
||||
VAddr m_address{};
|
||||
KProcessAddress m_address{};
|
||||
Svc::MemoryPermission m_owner_perm{};
|
||||
size_t m_size{};
|
||||
bool m_is_initialized{};
|
||||
|
12
src/core/hle/kernel/k_typed_address.h
Normal file
12
src/core/hle/kernel/k_typed_address.h
Normal file
@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/typed_address.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
using KPhysicalAddress = Common::PhysicalAddress;
|
||||
using KVirtualAddress = Common::VirtualAddress;
|
||||
using KProcessAddress = Common::ProcessAddress;
|
||||
|
||||
} // namespace Kernel
|
@ -271,9 +271,9 @@ struct KernelCore::Impl {
|
||||
system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event);
|
||||
}
|
||||
|
||||
void InitializeResourceManagers(KernelCore& kernel, VAddr address, size_t size) {
|
||||
void InitializeResourceManagers(KernelCore& kernel, KVirtualAddress address, size_t size) {
|
||||
// Ensure that the buffer is suitable for our use.
|
||||
ASSERT(Common::IsAligned(address, PageSize));
|
||||
ASSERT(Common::IsAligned(GetInteger(address), PageSize));
|
||||
ASSERT(Common::IsAligned(size, PageSize));
|
||||
|
||||
// Ensure that we have space for our reference counts.
|
||||
@ -462,29 +462,30 @@ struct KernelCore::Impl {
|
||||
KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1);
|
||||
|
||||
// Save start and end for ease of use.
|
||||
const VAddr code_start_virt_addr = KernelVirtualAddressCodeBase;
|
||||
const VAddr code_end_virt_addr = KernelVirtualAddressCodeEnd;
|
||||
constexpr KVirtualAddress code_start_virt_addr = KernelVirtualAddressCodeBase;
|
||||
constexpr KVirtualAddress code_end_virt_addr = KernelVirtualAddressCodeEnd;
|
||||
|
||||
// Setup the containing kernel region.
|
||||
constexpr size_t KernelRegionSize = 1_GiB;
|
||||
constexpr size_t KernelRegionAlign = 1_GiB;
|
||||
constexpr VAddr kernel_region_start =
|
||||
Common::AlignDown(code_start_virt_addr, KernelRegionAlign);
|
||||
constexpr KVirtualAddress kernel_region_start =
|
||||
Common::AlignDown(GetInteger(code_start_virt_addr), KernelRegionAlign);
|
||||
size_t kernel_region_size = KernelRegionSize;
|
||||
if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) {
|
||||
kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start;
|
||||
kernel_region_size = KernelVirtualAddressSpaceEnd - GetInteger(kernel_region_start);
|
||||
}
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel));
|
||||
GetInteger(kernel_region_start), kernel_region_size, KMemoryRegionType_Kernel));
|
||||
|
||||
// Setup the code region.
|
||||
constexpr size_t CodeRegionAlign = PageSize;
|
||||
constexpr VAddr code_region_start =
|
||||
Common::AlignDown(code_start_virt_addr, CodeRegionAlign);
|
||||
constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign);
|
||||
constexpr KVirtualAddress code_region_start =
|
||||
Common::AlignDown(GetInteger(code_start_virt_addr), CodeRegionAlign);
|
||||
constexpr KVirtualAddress code_region_end =
|
||||
Common::AlignUp(GetInteger(code_end_virt_addr), CodeRegionAlign);
|
||||
constexpr size_t code_region_size = code_region_end - code_region_start;
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
code_region_start, code_region_size, KMemoryRegionType_KernelCode));
|
||||
GetInteger(code_region_start), code_region_size, KMemoryRegionType_KernelCode));
|
||||
|
||||
// Setup board-specific device physical regions.
|
||||
Init::SetupDevicePhysicalMemoryRegions(*memory_layout);
|
||||
@ -520,11 +521,11 @@ struct KernelCore::Impl {
|
||||
ASSERT(misc_region_size > 0);
|
||||
|
||||
// Setup the misc region.
|
||||
const VAddr misc_region_start =
|
||||
const KVirtualAddress misc_region_start =
|
||||
memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
|
||||
misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel);
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc));
|
||||
GetInteger(misc_region_start), misc_region_size, KMemoryRegionType_KernelMisc));
|
||||
|
||||
// Determine if we'll use extra thread resources.
|
||||
const bool use_extra_resources = KSystemControl::Init::ShouldIncreaseThreadResourceLimit();
|
||||
@ -532,11 +533,11 @@ struct KernelCore::Impl {
|
||||
// Setup the stack region.
|
||||
constexpr size_t StackRegionSize = 14_MiB;
|
||||
constexpr size_t StackRegionAlign = KernelAslrAlignment;
|
||||
const VAddr stack_region_start =
|
||||
const KVirtualAddress stack_region_start =
|
||||
memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
|
||||
StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel);
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack));
|
||||
GetInteger(stack_region_start), StackRegionSize, KMemoryRegionType_KernelStack));
|
||||
|
||||
// Determine the size of the resource region.
|
||||
const size_t resource_region_size =
|
||||
@ -548,29 +549,29 @@ struct KernelCore::Impl {
|
||||
ASSERT(slab_region_size <= resource_region_size);
|
||||
|
||||
// Setup the slab region.
|
||||
const PAddr code_start_phys_addr = KernelPhysicalAddressCodeBase;
|
||||
const PAddr code_end_phys_addr = code_start_phys_addr + code_region_size;
|
||||
const PAddr slab_start_phys_addr = code_end_phys_addr;
|
||||
const PAddr slab_end_phys_addr = slab_start_phys_addr + slab_region_size;
|
||||
const KPhysicalAddress code_start_phys_addr = KernelPhysicalAddressCodeBase;
|
||||
const KPhysicalAddress code_end_phys_addr = code_start_phys_addr + code_region_size;
|
||||
const KPhysicalAddress slab_start_phys_addr = code_end_phys_addr;
|
||||
const KPhysicalAddress slab_end_phys_addr = slab_start_phys_addr + slab_region_size;
|
||||
constexpr size_t SlabRegionAlign = KernelAslrAlignment;
|
||||
const size_t slab_region_needed_size =
|
||||
Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) -
|
||||
Common::AlignDown(code_end_phys_addr, SlabRegionAlign);
|
||||
const VAddr slab_region_start =
|
||||
Common::AlignUp(GetInteger(code_end_phys_addr) + slab_region_size, SlabRegionAlign) -
|
||||
Common::AlignDown(GetInteger(code_end_phys_addr), SlabRegionAlign);
|
||||
const KVirtualAddress slab_region_start =
|
||||
memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
|
||||
slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) +
|
||||
(code_end_phys_addr % SlabRegionAlign);
|
||||
(GetInteger(code_end_phys_addr) % SlabRegionAlign);
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab));
|
||||
GetInteger(slab_region_start), slab_region_size, KMemoryRegionType_KernelSlab));
|
||||
|
||||
// Setup the temp region.
|
||||
constexpr size_t TempRegionSize = 128_MiB;
|
||||
constexpr size_t TempRegionAlign = KernelAslrAlignment;
|
||||
const VAddr temp_region_start =
|
||||
const KVirtualAddress temp_region_start =
|
||||
memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
|
||||
TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel);
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize,
|
||||
KMemoryRegionType_KernelTemp));
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
GetInteger(temp_region_start), TempRegionSize, KMemoryRegionType_KernelTemp));
|
||||
|
||||
// Automatically map in devices that have auto-map attributes.
|
||||
for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
|
||||
@ -596,35 +597,37 @@ struct KernelCore::Impl {
|
||||
region.SetTypeAttribute(KMemoryRegionAttr_DidKernelMap);
|
||||
|
||||
// Create a virtual pair region and insert it into the tree.
|
||||
const PAddr map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize);
|
||||
const KPhysicalAddress map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize);
|
||||
const size_t map_size =
|
||||
Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr;
|
||||
const VAddr map_virt_addr =
|
||||
Common::AlignUp(region.GetEndAddress(), PageSize) - GetInteger(map_phys_addr);
|
||||
const KVirtualAddress map_virt_addr =
|
||||
memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
|
||||
map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize);
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice));
|
||||
region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr);
|
||||
GetInteger(map_virt_addr), map_size, KMemoryRegionType_KernelMiscMappedDevice));
|
||||
region.SetPairAddress(GetInteger(map_virt_addr) + region.GetAddress() -
|
||||
GetInteger(map_phys_addr));
|
||||
}
|
||||
|
||||
Init::SetupDramPhysicalMemoryRegions(*memory_layout);
|
||||
|
||||
// Insert a physical region for the kernel code region.
|
||||
ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
|
||||
code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode));
|
||||
GetInteger(code_start_phys_addr), code_region_size, KMemoryRegionType_DramKernelCode));
|
||||
|
||||
// Insert a physical region for the kernel slab region.
|
||||
ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
|
||||
slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab));
|
||||
GetInteger(slab_start_phys_addr), slab_region_size, KMemoryRegionType_DramKernelSlab));
|
||||
|
||||
// Determine size available for kernel page table heaps, requiring > 8 MB.
|
||||
const PAddr resource_end_phys_addr = slab_start_phys_addr + resource_region_size;
|
||||
const KPhysicalAddress resource_end_phys_addr = slab_start_phys_addr + resource_region_size;
|
||||
const size_t page_table_heap_size = resource_end_phys_addr - slab_end_phys_addr;
|
||||
ASSERT(page_table_heap_size / 4_MiB > 2);
|
||||
|
||||
// Insert a physical region for the kernel page table heap region
|
||||
ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
|
||||
slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap));
|
||||
GetInteger(slab_end_phys_addr), page_table_heap_size,
|
||||
KMemoryRegionType_DramKernelPtHeap));
|
||||
|
||||
// All DRAM regions that we haven't tagged by this point will be mapped under the linear
|
||||
// mapping. Tag them.
|
||||
@ -646,20 +649,21 @@ struct KernelCore::Impl {
|
||||
|
||||
// Setup the linear mapping region.
|
||||
constexpr size_t LinearRegionAlign = 1_GiB;
|
||||
const PAddr aligned_linear_phys_start =
|
||||
const KPhysicalAddress aligned_linear_phys_start =
|
||||
Common::AlignDown(linear_extents.GetAddress(), LinearRegionAlign);
|
||||
const size_t linear_region_size =
|
||||
Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) -
|
||||
aligned_linear_phys_start;
|
||||
const VAddr linear_region_start =
|
||||
GetInteger(aligned_linear_phys_start);
|
||||
const KVirtualAddress linear_region_start =
|
||||
memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
|
||||
linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign);
|
||||
|
||||
const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start;
|
||||
const u64 linear_region_phys_to_virt_diff =
|
||||
GetInteger(linear_region_start) - GetInteger(aligned_linear_phys_start);
|
||||
|
||||
// Map and create regions for all the linearly-mapped data.
|
||||
{
|
||||
PAddr cur_phys_addr = 0;
|
||||
KPhysicalAddress cur_phys_addr = 0;
|
||||
u64 cur_size = 0;
|
||||
for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
|
||||
if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
|
||||
@ -678,15 +682,16 @@ struct KernelCore::Impl {
|
||||
cur_size = region.GetSize();
|
||||
}
|
||||
|
||||
const VAddr region_virt_addr =
|
||||
const KVirtualAddress region_virt_addr =
|
||||
region.GetAddress() + linear_region_phys_to_virt_diff;
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
region_virt_addr, region.GetSize(),
|
||||
GetInteger(region_virt_addr), region.GetSize(),
|
||||
GetTypeForVirtualLinearMapping(region.GetType())));
|
||||
region.SetPairAddress(region_virt_addr);
|
||||
region.SetPairAddress(GetInteger(region_virt_addr));
|
||||
|
||||
KMemoryRegion* virt_region =
|
||||
memory_layout->GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr);
|
||||
memory_layout->GetVirtualMemoryRegionTree().FindModifiable(
|
||||
GetInteger(region_virt_addr));
|
||||
ASSERT(virt_region != nullptr);
|
||||
virt_region->SetPairAddress(region.GetAddress());
|
||||
}
|
||||
@ -694,10 +699,11 @@ struct KernelCore::Impl {
|
||||
|
||||
// Insert regions for the initial page table region.
|
||||
ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
|
||||
resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt));
|
||||
GetInteger(resource_end_phys_addr), KernelPageTableHeapSize,
|
||||
KMemoryRegionType_DramKernelInitPt));
|
||||
ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
|
||||
resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize,
|
||||
KMemoryRegionType_VirtualDramKernelInitPt));
|
||||
GetInteger(resource_end_phys_addr) + linear_region_phys_to_virt_diff,
|
||||
KernelPageTableHeapSize, KMemoryRegionType_VirtualDramKernelInitPt));
|
||||
|
||||
// All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to
|
||||
// some pool partition. Tag them.
|
||||
@ -969,12 +975,12 @@ void KernelCore::InvalidateAllInstructionCaches() {
|
||||
}
|
||||
}
|
||||
|
||||
void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
|
||||
void KernelCore::InvalidateCpuInstructionCacheRange(KProcessAddress addr, std::size_t size) {
|
||||
for (auto& physical_core : impl->cores) {
|
||||
if (!physical_core->IsInitialized()) {
|
||||
continue;
|
||||
}
|
||||
physical_core->ArmInterface().InvalidateCacheRange(addr, size);
|
||||
physical_core->ArmInterface().InvalidateCacheRange(GetInteger(addr), size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/kernel/k_auto_object.h"
|
||||
#include "core/hle/kernel/k_slab_heap.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/svc_common.h"
|
||||
|
||||
namespace Core {
|
||||
@ -185,7 +186,7 @@ public:
|
||||
|
||||
void InvalidateAllInstructionCaches();
|
||||
|
||||
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
|
||||
void InvalidateCpuInstructionCacheRange(KProcessAddress addr, std::size_t size);
|
||||
|
||||
/// Registers all kernel objects with the global emulation state, this is purely for tracking
|
||||
/// leaks after emulation has been shutdown.
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <array>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@ -14,7 +15,4 @@ constexpr std::size_t PageSize{1 << PageBits};
|
||||
|
||||
using Page = std::array<u8, PageSize>;
|
||||
|
||||
using KPhysicalAddress = PAddr;
|
||||
using KProcessAddress = VAddr;
|
||||
|
||||
} // namespace Kernel
|
||||
|
@ -37,7 +37,7 @@ constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) {
|
||||
} // namespace
|
||||
|
||||
// Wait for an address (via Address Arbiter)
|
||||
Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
|
||||
Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_type, s32 value,
|
||||
s64 timeout_ns) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}",
|
||||
address, arb_type, value, timeout_ns);
|
||||
@ -68,7 +68,7 @@ Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_t
|
||||
}
|
||||
|
||||
// Signals to an address (via Address Arbiter)
|
||||
Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value,
|
||||
Result SignalToAddress(Core::System& system, u64 address, SignalType signal_type, s32 value,
|
||||
s32 count) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}",
|
||||
address, signal_type, value, count);
|
||||
@ -82,12 +82,12 @@ Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_ty
|
||||
.SignalAddressArbiter(address, signal_type, value, count));
|
||||
}
|
||||
|
||||
Result WaitForAddress64(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
|
||||
Result WaitForAddress64(Core::System& system, u64 address, ArbitrationType arb_type, s32 value,
|
||||
s64 timeout_ns) {
|
||||
R_RETURN(WaitForAddress(system, address, arb_type, value, timeout_ns));
|
||||
}
|
||||
|
||||
Result SignalToAddress64(Core::System& system, VAddr address, SignalType signal_type, s32 value,
|
||||
Result SignalToAddress64(Core::System& system, u64 address, SignalType signal_type, s32 value,
|
||||
s32 count) {
|
||||
R_RETURN(SignalToAddress(system, address, signal_type, value, count));
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm)
|
||||
|
||||
} // namespace
|
||||
|
||||
Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64_t size) {
|
||||
Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size);
|
||||
|
||||
// Get kernel instance.
|
||||
@ -64,7 +64,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64
|
||||
}
|
||||
|
||||
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
|
||||
CodeMemoryOperation operation, VAddr address, uint64_t size,
|
||||
CodeMemoryOperation operation, u64 address, uint64_t size,
|
||||
MemoryPermission perm) {
|
||||
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
|
@ -11,7 +11,7 @@
|
||||
namespace Kernel::Svc {
|
||||
|
||||
/// Wait process wide key atomic
|
||||
Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag,
|
||||
Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 cv_key, u32 tag,
|
||||
s64 timeout_ns) {
|
||||
LOG_TRACE(Kernel_SVC, "called address={:X}, cv_key={:X}, tag=0x{:08X}, timeout_ns={}", address,
|
||||
cv_key, tag, timeout_ns);
|
||||
@ -43,7 +43,7 @@ Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_ke
|
||||
}
|
||||
|
||||
/// Signal process wide key
|
||||
void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) {
|
||||
void SignalProcessWideKey(Core::System& system, u64 cv_key, s32 count) {
|
||||
LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count);
|
||||
|
||||
// Signal the condition variable.
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace Kernel::Svc {
|
||||
|
||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
|
||||
Result OutputDebugString(Core::System& system, VAddr address, u64 len) {
|
||||
Result OutputDebugString(Core::System& system, u64 address, u64 len) {
|
||||
R_SUCCEED_IF(len == 0);
|
||||
|
||||
std::string str(len, '\0');
|
||||
|
@ -20,7 +20,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
|
||||
bool has_dumped_buffer{};
|
||||
std::vector<u8> debug_buffer;
|
||||
|
||||
const auto handle_debug_buffer = [&](VAddr addr, u64 sz) {
|
||||
const auto handle_debug_buffer = [&](u64 addr, u64 sz) {
|
||||
if (sz == 0 || addr == 0 || has_dumped_buffer) {
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::AliasRegionAddress:
|
||||
*result = process->PageTable().GetAliasRegionStart();
|
||||
*result = GetInteger(process->PageTable().GetAliasRegionStart());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::AliasRegionSize:
|
||||
@ -62,7 +62,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::HeapRegionAddress:
|
||||
*result = process->PageTable().GetHeapRegionStart();
|
||||
*result = GetInteger(process->PageTable().GetHeapRegionStart());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::HeapRegionSize:
|
||||
@ -70,7 +70,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::AslrRegionAddress:
|
||||
*result = process->PageTable().GetAliasCodeRegionStart();
|
||||
*result = GetInteger(process->PageTable().GetAliasCodeRegionStart());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::AslrRegionSize:
|
||||
@ -78,7 +78,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::StackRegionAddress:
|
||||
*result = process->PageTable().GetStackRegionStart();
|
||||
*result = GetInteger(process->PageTable().GetStackRegionStart());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::StackRegionSize:
|
||||
@ -107,7 +107,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::UserExceptionContextAddress:
|
||||
*result = process->GetProcessLocalRegionAddress();
|
||||
*result = GetInteger(process->GetProcessLocalRegionAddress());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::TotalNonSystemMemorySize:
|
||||
|
@ -9,7 +9,7 @@
|
||||
namespace Kernel::Svc {
|
||||
|
||||
/// Attempts to locks a mutex
|
||||
Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag) {
|
||||
Result ArbitrateLock(Core::System& system, Handle thread_handle, u64 address, u32 tag) {
|
||||
LOG_TRACE(Kernel_SVC, "called thread_handle=0x{:08X}, address=0x{:X}, tag=0x{:08X}",
|
||||
thread_handle, address, tag);
|
||||
|
||||
@ -21,7 +21,7 @@ Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address,
|
||||
}
|
||||
|
||||
/// Unlock a mutex
|
||||
Result ArbitrateUnlock(Core::System& system, VAddr address) {
|
||||
Result ArbitrateUnlock(Core::System& system, u64 address) {
|
||||
LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address);
|
||||
|
||||
// Validate the input address.
|
||||
|
@ -22,15 +22,14 @@ constexpr bool IsValidSetMemoryPermission(MemoryPermission perm) {
|
||||
// Checks if address + size is greater than the given address
|
||||
// This can return false if the size causes an overflow of a 64-bit type
|
||||
// or if the given size is zero.
|
||||
constexpr bool IsValidAddressRange(VAddr address, u64 size) {
|
||||
constexpr bool IsValidAddressRange(u64 address, u64 size) {
|
||||
return address + size > address;
|
||||
}
|
||||
|
||||
// Helper function that performs the common sanity checks for svcMapMemory
|
||||
// and svcUnmapMemory. This is doable, as both functions perform their sanitizing
|
||||
// in the same order.
|
||||
Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr,
|
||||
u64 size) {
|
||||
Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 src_addr, u64 size) {
|
||||
if (!Common::Is4KBAligned(dst_addr)) {
|
||||
LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr);
|
||||
R_THROW(ResultInvalidAddress);
|
||||
@ -99,7 +98,7 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAd
|
||||
|
||||
} // namespace
|
||||
|
||||
Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, MemoryPermission perm) {
|
||||
Result SetMemoryPermission(Core::System& system, u64 address, u64 size, MemoryPermission perm) {
|
||||
LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, perm=0x{:08X", address, size,
|
||||
perm);
|
||||
|
||||
@ -120,7 +119,7 @@ Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, Memory
|
||||
R_RETURN(page_table.SetMemoryPermission(address, size, perm));
|
||||
}
|
||||
|
||||
Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, u32 attr) {
|
||||
Result SetMemoryAttribute(Core::System& system, u64 address, u64 size, u32 mask, u32 attr) {
|
||||
LOG_DEBUG(Kernel_SVC,
|
||||
"called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
|
||||
size, mask, attr);
|
||||
@ -145,7 +144,7 @@ Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mas
|
||||
}
|
||||
|
||||
/// Maps a memory range into a different range.
|
||||
Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
Result MapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||
src_addr, size);
|
||||
|
||||
@ -160,7 +159,7 @@ Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size)
|
||||
}
|
||||
|
||||
/// Unmaps a region that was previously mapped with svcMapMemory
|
||||
Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
Result UnmapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||
src_addr, size);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace Kernel::Svc {
|
||||
|
||||
/// Set the process heap to a given Size. It can both extend and shrink the heap.
|
||||
Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) {
|
||||
Result SetHeapSize(Core::System& system, u64* out_address, u64 size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", size);
|
||||
|
||||
// Validate size.
|
||||
@ -20,7 +20,7 @@ Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) {
|
||||
}
|
||||
|
||||
/// Maps memory at a desired address
|
||||
Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
|
||||
Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
|
||||
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
|
||||
|
||||
if (!Common::Is4KBAligned(addr)) {
|
||||
@ -69,7 +69,7 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
|
||||
}
|
||||
|
||||
/// Unmaps memory previously mapped via MapPhysicalMemory
|
||||
Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
|
||||
Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
|
||||
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
|
||||
|
||||
if (!Common::Is4KBAligned(addr)) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
namespace Kernel::Svc {
|
||||
|
||||
Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) {
|
||||
Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) {
|
||||
// Copy the provided name from user memory to kernel memory.
|
||||
auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
|
||||
|
||||
|
@ -50,7 +50,7 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_process_ids,
|
||||
Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_process_ids,
|
||||
int32_t out_process_ids_size) {
|
||||
LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}",
|
||||
out_process_ids, out_process_ids_size);
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace Kernel::Svc {
|
||||
namespace {
|
||||
|
||||
constexpr bool IsValidAddressRange(VAddr address, u64 size) {
|
||||
constexpr bool IsValidAddressRange(u64 address, u64 size) {
|
||||
return address + size > address;
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) {
|
||||
|
||||
} // namespace
|
||||
|
||||
Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address,
|
||||
Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u64 address,
|
||||
u64 size, Svc::MemoryPermission perm) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
||||
@ -56,8 +56,8 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, V
|
||||
R_RETURN(page_table.SetProcessMemoryPermission(address, size, perm));
|
||||
}
|
||||
|
||||
Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle,
|
||||
VAddr src_address, u64 size) {
|
||||
Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_handle,
|
||||
u64 src_address, u64 size) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}",
|
||||
dst_address, process_handle, src_address, size);
|
||||
@ -97,8 +97,8 @@ Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_
|
||||
KMemoryPermission::UserReadWrite));
|
||||
}
|
||||
|
||||
Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle,
|
||||
VAddr src_address, u64 size) {
|
||||
Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_handle,
|
||||
u64 src_address, u64 size) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}",
|
||||
dst_address, process_handle, src_address, size);
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace Kernel::Svc {
|
||||
|
||||
Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info,
|
||||
VAddr query_address) {
|
||||
u64 query_address) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, out_memory_info=0x{:016X}, "
|
||||
"query_address=0x{:016X}",
|
||||
|
@ -26,7 +26,7 @@ constexpr bool IsValidSharedMemoryPermission(MemoryPermission perm) {
|
||||
|
||||
} // namespace
|
||||
|
||||
Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size,
|
||||
Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u64 size,
|
||||
Svc::MemoryPermission map_perm) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
||||
@ -64,7 +64,7 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address,
|
||||
R_RETURN(shmem->Map(process, address, size, map_perm));
|
||||
}
|
||||
|
||||
Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size) {
|
||||
Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u64 size) {
|
||||
// Validate the address/size.
|
||||
R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
|
||||
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
|
||||
|
@ -80,7 +80,7 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
|
||||
}
|
||||
|
||||
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
||||
Result WaitSynchronization(Core::System& system, int32_t* out_index, VAddr user_handles,
|
||||
Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_handles,
|
||||
int32_t num_handles, int64_t timeout_ns) {
|
||||
LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles,
|
||||
num_handles, timeout_ns);
|
||||
|
@ -19,8 +19,8 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) {
|
||||
} // Anonymous namespace
|
||||
|
||||
/// Creates a new thread
|
||||
Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
|
||||
VAddr stack_bottom, s32 priority, s32 core_id) {
|
||||
Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u64 arg,
|
||||
u64 stack_bottom, s32 priority, s32 core_id) {
|
||||
LOG_DEBUG(Kernel_SVC,
|
||||
"called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, "
|
||||
"priority=0x{:08X}, core_id=0x{:08X}",
|
||||
@ -129,7 +129,7 @@ void SleepThread(Core::System& system, s64 nanoseconds) {
|
||||
}
|
||||
|
||||
/// Gets the thread context
|
||||
Result GetThreadContext3(Core::System& system, VAddr out_context, Handle thread_handle) {
|
||||
Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_handle) {
|
||||
LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context,
|
||||
thread_handle);
|
||||
|
||||
@ -217,7 +217,7 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priorit
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetThreadList(Core::System& system, s32* out_num_threads, VAddr out_thread_ids,
|
||||
Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_ids,
|
||||
s32 out_thread_ids_size, Handle debug_handle) {
|
||||
// TODO: Handle this case when debug events are supported.
|
||||
UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
|
||||
|
@ -25,7 +25,7 @@ constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) {
|
||||
} // Anonymous namespace
|
||||
|
||||
/// Creates a TransferMemory object
|
||||
Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size,
|
||||
Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64 size,
|
||||
MemoryPermission map_perm) {
|
||||
auto& kernel = system.Kernel();
|
||||
|
||||
|
@ -253,7 +253,7 @@ struct LastThreadContext {
|
||||
};
|
||||
|
||||
struct PhysicalMemoryInfo {
|
||||
PAddr physical_address;
|
||||
u64 physical_address;
|
||||
u64 virtual_address;
|
||||
u64 size;
|
||||
};
|
||||
@ -359,7 +359,7 @@ struct LastThreadContext {
|
||||
};
|
||||
|
||||
struct PhysicalMemoryInfo {
|
||||
PAddr physical_address;
|
||||
u64 physical_address;
|
||||
u32 virtual_address;
|
||||
u32 size;
|
||||
};
|
||||
|
Reference in New Issue
Block a user