Merge pull request #2748 from FernandoS27/align-memory
VM_Manager: Align allocated host physical memory to 256bytes
This commit is contained in:
commit
b4a8cfbd00
15 changed files with 119 additions and 37 deletions
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
@ -37,4 +38,63 @@ constexpr bool IsWordAligned(T value) {
|
||||||
return (value & 0b11) == 0;
|
return (value & 0b11) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Align = 16>
|
||||||
|
class AlignmentAllocator {
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
using size_type = std::size_t;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
|
using pointer = T*;
|
||||||
|
using const_pointer = const T*;
|
||||||
|
|
||||||
|
using reference = T&;
|
||||||
|
using const_reference = const T&;
|
||||||
|
|
||||||
|
public:
|
||||||
|
pointer address(reference r) noexcept {
|
||||||
|
return std::addressof(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer address(const_reference r) const noexcept {
|
||||||
|
return std::addressof(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer allocate(size_type n) {
|
||||||
|
return static_cast<pointer>(::operator new (n, std::align_val_t{Align}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(pointer p, size_type) {
|
||||||
|
::operator delete (p, std::align_val_t{Align});
|
||||||
|
}
|
||||||
|
|
||||||
|
void construct(pointer p, const value_type& wert) {
|
||||||
|
new (p) value_type(wert);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(pointer p) {
|
||||||
|
p->~value_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type max_size() const noexcept {
|
||||||
|
return size_type(-1) / sizeof(value_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T2>
|
||||||
|
struct rebind {
|
||||||
|
using other = AlignmentAllocator<T2, Align>;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator!=(const AlignmentAllocator<T, Align>& other) const noexcept {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if and only if storage allocated from *this
|
||||||
|
// can be deallocated from other, and vice versa.
|
||||||
|
// Always returns true for stateless allocators.
|
||||||
|
bool operator==(const AlignmentAllocator<T, Align>& other) const noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/kernel/physical_memory.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ struct CodeSet final {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The overall data that backs this code set.
|
/// The overall data that backs this code set.
|
||||||
std::vector<u8> memory;
|
Kernel::PhysicalMemory memory;
|
||||||
|
|
||||||
/// The segments that comprise this code set.
|
/// The segments that comprise this code set.
|
||||||
std::array<Segment, 3> segments;
|
std::array<Segment, 3> segments;
|
||||||
|
|
19
src/core/hle/kernel/physical_memory.h
Normal file
19
src/core/hle/kernel/physical_memory.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2019 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/alignment.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
// This encapsulation serves 2 purposes:
|
||||||
|
// - First, to encapsulate host physical memory under a single type and set an
|
||||||
|
// standard for managing it.
|
||||||
|
// - Second to ensure all host backing memory used is aligned to 256 bytes due
|
||||||
|
// to strict alignment restrictions on GPU memory.
|
||||||
|
|
||||||
|
using PhysicalMemory = std::vector<u8, Common::AlignmentAllocator<u8, 256>>;
|
||||||
|
|
||||||
|
} // namespace Kernel
|
|
@ -247,7 +247,7 @@ VAddr Process::CreateTLSRegion() {
|
||||||
ASSERT(region_address.Succeeded());
|
ASSERT(region_address.Succeeded());
|
||||||
|
|
||||||
const auto map_result = vm_manager.MapMemoryBlock(
|
const auto map_result = vm_manager.MapMemoryBlock(
|
||||||
*region_address, std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE), 0,
|
*region_address, std::make_shared<PhysicalMemory>(Memory::PAGE_SIZE), 0,
|
||||||
Memory::PAGE_SIZE, MemoryState::ThreadLocal);
|
Memory::PAGE_SIZE, MemoryState::ThreadLocal);
|
||||||
ASSERT(map_result.Succeeded());
|
ASSERT(map_result.Succeeded());
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ void Process::FreeTLSRegion(VAddr tls_address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::LoadModule(CodeSet module_, VAddr base_addr) {
|
void Process::LoadModule(CodeSet module_, VAddr base_addr) {
|
||||||
const auto memory = std::make_shared<std::vector<u8>>(std::move(module_.memory));
|
const auto memory = std::make_shared<PhysicalMemory>(std::move(module_.memory));
|
||||||
|
|
||||||
const auto MapSegment = [&](const CodeSet::Segment& segment, VMAPermission permissions,
|
const auto MapSegment = [&](const CodeSet::Segment& segment, VMAPermission permissions,
|
||||||
MemoryState memory_state) {
|
MemoryState memory_state) {
|
||||||
|
@ -327,7 +327,7 @@ void Process::AllocateMainThreadStack(u64 stack_size) {
|
||||||
// Allocate and map the main thread stack
|
// Allocate and map the main thread stack
|
||||||
const VAddr mapping_address = vm_manager.GetTLSIORegionEndAddress() - main_thread_stack_size;
|
const VAddr mapping_address = vm_manager.GetTLSIORegionEndAddress() - main_thread_stack_size;
|
||||||
vm_manager
|
vm_manager
|
||||||
.MapMemoryBlock(mapping_address, std::make_shared<std::vector<u8>>(main_thread_stack_size),
|
.MapMemoryBlock(mapping_address, std::make_shared<PhysicalMemory>(main_thread_stack_size),
|
||||||
0, main_thread_stack_size, MemoryState::Stack)
|
0, main_thread_stack_size, MemoryState::Stack)
|
||||||
.Unwrap();
|
.Unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_
|
||||||
shared_memory->other_permissions = other_permissions;
|
shared_memory->other_permissions = other_permissions;
|
||||||
|
|
||||||
if (address == 0) {
|
if (address == 0) {
|
||||||
shared_memory->backing_block = std::make_shared<std::vector<u8>>(size);
|
shared_memory->backing_block = std::make_shared<Kernel::PhysicalMemory>(size);
|
||||||
shared_memory->backing_block_offset = 0;
|
shared_memory->backing_block_offset = 0;
|
||||||
|
|
||||||
// Refresh the address mappings for the current process.
|
// Refresh the address mappings for the current process.
|
||||||
|
@ -59,8 +59,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
|
SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
|
||||||
KernelCore& kernel, std::shared_ptr<std::vector<u8>> heap_block, std::size_t offset, u64 size,
|
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
|
||||||
MemoryPermission permissions, MemoryPermission other_permissions, std::string name) {
|
u64 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) {
|
||||||
SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
|
SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
|
||||||
|
|
||||||
shared_memory->owner_process = nullptr;
|
shared_memory->owner_process = nullptr;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
|
#include "core/hle/kernel/physical_memory.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
@ -62,11 +63,9 @@ public:
|
||||||
* block.
|
* block.
|
||||||
* @param name Optional object name, used for debugging purposes.
|
* @param name Optional object name, used for debugging purposes.
|
||||||
*/
|
*/
|
||||||
static SharedPtr<SharedMemory> CreateForApplet(KernelCore& kernel,
|
static SharedPtr<SharedMemory> CreateForApplet(
|
||||||
std::shared_ptr<std::vector<u8>> heap_block,
|
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
|
||||||
std::size_t offset, u64 size,
|
u64 size, MemoryPermission permissions, MemoryPermission other_permissions,
|
||||||
MemoryPermission permissions,
|
|
||||||
MemoryPermission other_permissions,
|
|
||||||
std::string name = "Unknown Applet");
|
std::string name = "Unknown Applet");
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
|
@ -135,7 +134,7 @@ private:
|
||||||
~SharedMemory() override;
|
~SharedMemory() override;
|
||||||
|
|
||||||
/// Backing memory for this shared memory block.
|
/// Backing memory for this shared memory block.
|
||||||
std::shared_ptr<std::vector<u8>> backing_block;
|
std::shared_ptr<PhysicalMemory> backing_block;
|
||||||
/// Offset into the backing block for this shared memory.
|
/// Offset into the backing block for this shared memory.
|
||||||
std::size_t backing_block_offset = 0;
|
std::size_t backing_block_offset = 0;
|
||||||
/// Size of the memory block. Page-aligned.
|
/// Size of the memory block. Page-aligned.
|
||||||
|
|
|
@ -47,7 +47,7 @@ ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission p
|
||||||
return ERR_INVALID_STATE;
|
return ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
backing_block = std::make_shared<std::vector<u8>>(size);
|
backing_block = std::make_shared<PhysicalMemory>(size);
|
||||||
|
|
||||||
const auto map_state = owner_permissions == MemoryPermission::None
|
const auto map_state = owner_permissions == MemoryPermission::None
|
||||||
? MemoryState::TransferMemoryIsolated
|
? MemoryState::TransferMemoryIsolated
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
|
#include "core/hle/kernel/physical_memory.h"
|
||||||
|
|
||||||
union ResultCode;
|
union ResultCode;
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ private:
|
||||||
~TransferMemory() override;
|
~TransferMemory() override;
|
||||||
|
|
||||||
/// Memory block backing this instance.
|
/// Memory block backing this instance.
|
||||||
std::shared_ptr<std::vector<u8>> backing_block;
|
std::shared_ptr<PhysicalMemory> backing_block;
|
||||||
|
|
||||||
/// The base address for the memory managed by this instance.
|
/// The base address for the memory managed by this instance.
|
||||||
VAddr base_address = 0;
|
VAddr base_address = 0;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "common/alignment.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/memory_hook.h"
|
#include "common/memory_hook.h"
|
||||||
|
@ -103,7 +104,7 @@ bool VMManager::IsValidHandle(VMAHandle handle) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
|
ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
|
||||||
std::shared_ptr<std::vector<u8>> block,
|
std::shared_ptr<PhysicalMemory> block,
|
||||||
std::size_t offset, u64 size,
|
std::size_t offset, u64 size,
|
||||||
MemoryState state, VMAPermission perm) {
|
MemoryState state, VMAPermission perm) {
|
||||||
ASSERT(block != nullptr);
|
ASSERT(block != nullptr);
|
||||||
|
@ -260,7 +261,7 @@ ResultVal<VAddr> VMManager::SetHeapSize(u64 size) {
|
||||||
|
|
||||||
if (heap_memory == nullptr) {
|
if (heap_memory == nullptr) {
|
||||||
// Initialize heap
|
// Initialize heap
|
||||||
heap_memory = std::make_shared<std::vector<u8>>(size);
|
heap_memory = std::make_shared<PhysicalMemory>(size);
|
||||||
heap_end = heap_region_base + size;
|
heap_end = heap_region_base + size;
|
||||||
} else {
|
} else {
|
||||||
UnmapRange(heap_region_base, GetCurrentHeapSize());
|
UnmapRange(heap_region_base, GetCurrentHeapSize());
|
||||||
|
@ -341,7 +342,7 @@ ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
|
||||||
const auto map_size = std::min(end_addr - cur_addr, vma_end - cur_addr);
|
const auto map_size = std::min(end_addr - cur_addr, vma_end - cur_addr);
|
||||||
if (vma.state == MemoryState::Unmapped) {
|
if (vma.state == MemoryState::Unmapped) {
|
||||||
const auto map_res =
|
const auto map_res =
|
||||||
MapMemoryBlock(cur_addr, std::make_shared<std::vector<u8>>(map_size, 0), 0,
|
MapMemoryBlock(cur_addr, std::make_shared<PhysicalMemory>(map_size, 0), 0,
|
||||||
map_size, MemoryState::Heap, VMAPermission::ReadWrite);
|
map_size, MemoryState::Heap, VMAPermission::ReadWrite);
|
||||||
result = map_res.Code();
|
result = map_res.Code();
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
|
@ -442,7 +443,7 @@ ResultCode VMManager::UnmapPhysicalMemory(VAddr target, u64 size) {
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
for (const auto [map_address, map_size] : unmapped_regions) {
|
for (const auto [map_address, map_size] : unmapped_regions) {
|
||||||
const auto remap_res =
|
const auto remap_res =
|
||||||
MapMemoryBlock(map_address, std::make_shared<std::vector<u8>>(map_size, 0), 0,
|
MapMemoryBlock(map_address, std::make_shared<PhysicalMemory>(map_size, 0), 0,
|
||||||
map_size, MemoryState::Heap, VMAPermission::None);
|
map_size, MemoryState::Heap, VMAPermission::None);
|
||||||
ASSERT_MSG(remap_res.Succeeded(), "UnmapPhysicalMemory re-map on error");
|
ASSERT_MSG(remap_res.Succeeded(), "UnmapPhysicalMemory re-map on error");
|
||||||
}
|
}
|
||||||
|
@ -593,7 +594,7 @@ ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, Mem
|
||||||
ASSERT_MSG(vma_offset + size <= vma->second.size,
|
ASSERT_MSG(vma_offset + size <= vma->second.size,
|
||||||
"Shared memory exceeds bounds of mapped block");
|
"Shared memory exceeds bounds of mapped block");
|
||||||
|
|
||||||
const std::shared_ptr<std::vector<u8>>& backing_block = vma->second.backing_block;
|
const std::shared_ptr<PhysicalMemory>& backing_block = vma->second.backing_block;
|
||||||
const std::size_t backing_block_offset = vma->second.offset + vma_offset;
|
const std::size_t backing_block_offset = vma->second.offset + vma_offset;
|
||||||
|
|
||||||
CASCADE_RESULT(auto new_vma,
|
CASCADE_RESULT(auto new_vma,
|
||||||
|
@ -606,7 +607,7 @@ ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, Mem
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMManager::RefreshMemoryBlockMappings(const std::vector<u8>* block) {
|
void VMManager::RefreshMemoryBlockMappings(const PhysicalMemory* block) {
|
||||||
// If this ever proves to have a noticeable performance impact, allow users of the function to
|
// If this ever proves to have a noticeable performance impact, allow users of the function to
|
||||||
// specify a specific range of addresses to limit the scan to.
|
// specify a specific range of addresses to limit the scan to.
|
||||||
for (const auto& p : vma_map) {
|
for (const auto& p : vma_map) {
|
||||||
|
@ -764,7 +765,7 @@ void VMManager::MergeAdjacentVMA(VirtualMemoryArea& left, const VirtualMemoryAre
|
||||||
right.backing_block->begin() + right.offset + right.size);
|
right.backing_block->begin() + right.offset + right.size);
|
||||||
} else {
|
} else {
|
||||||
// Slow case: make a new memory block for left and right.
|
// Slow case: make a new memory block for left and right.
|
||||||
auto new_memory = std::make_shared<std::vector<u8>>();
|
auto new_memory = std::make_shared<PhysicalMemory>();
|
||||||
new_memory->insert(new_memory->end(), left.backing_block->begin() + left.offset,
|
new_memory->insert(new_memory->end(), left.backing_block->begin() + left.offset,
|
||||||
left.backing_block->begin() + left.offset + left.size);
|
left.backing_block->begin() + left.offset + left.size);
|
||||||
new_memory->insert(new_memory->end(), right.backing_block->begin() + right.offset,
|
new_memory->insert(new_memory->end(), right.backing_block->begin() + right.offset,
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/memory_hook.h"
|
#include "common/memory_hook.h"
|
||||||
#include "common/page_table.h"
|
#include "common/page_table.h"
|
||||||
|
#include "core/hle/kernel/physical_memory.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
@ -290,7 +291,7 @@ struct VirtualMemoryArea {
|
||||||
|
|
||||||
// Settings for type = AllocatedMemoryBlock
|
// Settings for type = AllocatedMemoryBlock
|
||||||
/// Memory block backing this VMA.
|
/// Memory block backing this VMA.
|
||||||
std::shared_ptr<std::vector<u8>> backing_block = nullptr;
|
std::shared_ptr<PhysicalMemory> backing_block = nullptr;
|
||||||
/// Offset into the backing_memory the mapping starts from.
|
/// Offset into the backing_memory the mapping starts from.
|
||||||
std::size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
|
|
||||||
|
@ -348,7 +349,7 @@ public:
|
||||||
* @param size Size of the mapping.
|
* @param size Size of the mapping.
|
||||||
* @param state MemoryState tag to attach to the VMA.
|
* @param state MemoryState tag to attach to the VMA.
|
||||||
*/
|
*/
|
||||||
ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block,
|
ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<PhysicalMemory> block,
|
||||||
std::size_t offset, u64 size, MemoryState state,
|
std::size_t offset, u64 size, MemoryState state,
|
||||||
VMAPermission perm = VMAPermission::ReadWrite);
|
VMAPermission perm = VMAPermission::ReadWrite);
|
||||||
|
|
||||||
|
@ -547,7 +548,7 @@ public:
|
||||||
* Scans all VMAs and updates the page table range of any that use the given vector as backing
|
* Scans all VMAs and updates the page table range of any that use the given vector as backing
|
||||||
* memory. This should be called after any operation that causes reallocation of the vector.
|
* memory. This should be called after any operation that causes reallocation of the vector.
|
||||||
*/
|
*/
|
||||||
void RefreshMemoryBlockMappings(const std::vector<u8>* block);
|
void RefreshMemoryBlockMappings(const PhysicalMemory* block);
|
||||||
|
|
||||||
/// Dumps the address space layout to the log, for debugging
|
/// Dumps the address space layout to the log, for debugging
|
||||||
void LogLayout() const;
|
void LogLayout() const;
|
||||||
|
@ -777,7 +778,7 @@ private:
|
||||||
// the entire virtual address space extents that bound the allocations, including any holes.
|
// the entire virtual address space extents that bound the allocations, including any holes.
|
||||||
// This makes deallocation and reallocation of holes fast and keeps process memory contiguous
|
// This makes deallocation and reallocation of holes fast and keeps process memory contiguous
|
||||||
// in the emulator address space, allowing Memory::GetPointer to be reasonably safe.
|
// in the emulator address space, allowing Memory::GetPointer to be reasonably safe.
|
||||||
std::shared_ptr<std::vector<u8>> heap_memory;
|
std::shared_ptr<PhysicalMemory> heap_memory;
|
||||||
|
|
||||||
// The end of the currently allocated heap. This is not an inclusive
|
// The end of the currently allocated heap. This is not an inclusive
|
||||||
// end of the range. This is essentially 'base_address + current_size'.
|
// end of the range. This is essentially 'base_address + current_size'.
|
||||||
|
|
|
@ -77,7 +77,7 @@ enum class LoadState : u32 {
|
||||||
Done = 1,
|
Done = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output,
|
static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMemory& output,
|
||||||
std::size_t& offset) {
|
std::size_t& offset) {
|
||||||
ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE,
|
ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE,
|
||||||
"Shared fonts exceeds 17mb!");
|
"Shared fonts exceeds 17mb!");
|
||||||
|
@ -94,7 +94,7 @@ static void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& ou
|
||||||
offset += transformed_font.size() * sizeof(u32);
|
offset += transformed_font.size() * sizeof(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output,
|
static void EncryptSharedFont(const std::vector<u8>& input, Kernel::PhysicalMemory& output,
|
||||||
std::size_t& offset) {
|
std::size_t& offset) {
|
||||||
ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!");
|
ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!");
|
||||||
const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT;
|
const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT;
|
||||||
|
@ -121,7 +121,7 @@ struct PL_U::Impl {
|
||||||
return shared_font_regions.at(index);
|
return shared_font_regions.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildSharedFontsRawRegions(const std::vector<u8>& input) {
|
void BuildSharedFontsRawRegions(const Kernel::PhysicalMemory& input) {
|
||||||
// As we can derive the xor key we can just populate the offsets
|
// As we can derive the xor key we can just populate the offsets
|
||||||
// based on the shared memory dump
|
// based on the shared memory dump
|
||||||
unsigned cur_offset = 0;
|
unsigned cur_offset = 0;
|
||||||
|
@ -144,7 +144,7 @@ struct PL_U::Impl {
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
|
Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
|
||||||
|
|
||||||
/// Backing memory for the shared font data
|
/// Backing memory for the shared font data
|
||||||
std::shared_ptr<std::vector<u8>> shared_font;
|
std::shared_ptr<Kernel::PhysicalMemory> shared_font;
|
||||||
|
|
||||||
// Automatically populated based on shared_fonts dump or system archives.
|
// Automatically populated based on shared_fonts dump or system archives.
|
||||||
std::vector<FontRegion> shared_font_regions;
|
std::vector<FontRegion> shared_font_regions;
|
||||||
|
@ -166,7 +166,7 @@ PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} {
|
||||||
// Rebuild shared fonts from data ncas
|
// Rebuild shared fonts from data ncas
|
||||||
if (nand->HasEntry(static_cast<u64>(FontArchives::Standard),
|
if (nand->HasEntry(static_cast<u64>(FontArchives::Standard),
|
||||||
FileSys::ContentRecordType::Data)) {
|
FileSys::ContentRecordType::Data)) {
|
||||||
impl->shared_font = std::make_shared<std::vector<u8>>(SHARED_FONT_MEM_SIZE);
|
impl->shared_font = std::make_shared<Kernel::PhysicalMemory>(SHARED_FONT_MEM_SIZE);
|
||||||
for (auto font : SHARED_FONTS) {
|
for (auto font : SHARED_FONTS) {
|
||||||
const auto nca =
|
const auto nca =
|
||||||
nand->GetEntry(static_cast<u64>(font.first), FileSys::ContentRecordType::Data);
|
nand->GetEntry(static_cast<u64>(font.first), FileSys::ContentRecordType::Data);
|
||||||
|
@ -207,7 +207,7 @@ PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
impl->shared_font = std::make_shared<std::vector<u8>>(
|
impl->shared_font = std::make_shared<Kernel::PhysicalMemory>(
|
||||||
SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size
|
SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size
|
||||||
|
|
||||||
const std::string user_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir);
|
const std::string user_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir);
|
||||||
|
|
|
@ -295,7 +295,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> program_image(total_image_size);
|
Kernel::PhysicalMemory program_image(total_image_size);
|
||||||
std::size_t current_image_position = 0;
|
std::size_t current_image_position = 0;
|
||||||
|
|
||||||
Kernel::CodeSet codeset;
|
Kernel::CodeSet codeset;
|
||||||
|
|
|
@ -69,7 +69,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process) {
|
||||||
|
|
||||||
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
|
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
|
||||||
Kernel::CodeSet codeset;
|
Kernel::CodeSet codeset;
|
||||||
std::vector<u8> program_image;
|
Kernel::PhysicalMemory program_image;
|
||||||
|
|
||||||
const auto load_segment = [&program_image](Kernel::CodeSet::Segment& segment,
|
const auto load_segment = [&program_image](Kernel::CodeSet::Segment& segment,
|
||||||
const std::vector<u8>& data, u32 offset) {
|
const std::vector<u8>& data, u32 offset) {
|
||||||
|
|
|
@ -143,7 +143,7 @@ static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build program image
|
// Build program image
|
||||||
std::vector<u8> program_image(PageAlignSize(nro_header.file_size));
|
Kernel::PhysicalMemory program_image(PageAlignSize(nro_header.file_size));
|
||||||
std::memcpy(program_image.data(), data.data(), program_image.size());
|
std::memcpy(program_image.data(), data.data(), program_image.size());
|
||||||
if (program_image.size() != PageAlignSize(nro_header.file_size)) {
|
if (program_image.size() != PageAlignSize(nro_header.file_size)) {
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -89,7 +89,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
|
||||||
|
|
||||||
// Build program image
|
// Build program image
|
||||||
Kernel::CodeSet codeset;
|
Kernel::CodeSet codeset;
|
||||||
std::vector<u8> program_image;
|
Kernel::PhysicalMemory program_image;
|
||||||
for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
|
for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
|
||||||
std::vector<u8> data =
|
std::vector<u8> data =
|
||||||
file.ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset);
|
file.ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset);
|
||||||
|
|
Loading…
Reference in a new issue