summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/core.cpp6
-rw-r--r--src/core/core.h3
-rw-r--r--src/core/hle/kernel/kernel.cpp6
-rw-r--r--src/core/hle/kernel/kernel.h2
-rw-r--r--src/core/hle/kernel/memory.cpp90
-rw-r--r--src/core/hle/kernel/memory.h34
-rw-r--r--src/core/hle/kernel/process.cpp84
-rw-r--r--src/core/hle/kernel/process.h62
-rw-r--r--src/core/hle/kernel/shared_memory.cpp35
-rw-r--r--src/core/hle/kernel/shared_memory.h3
-rw-r--r--src/core/hle/kernel/thread.cpp34
-rw-r--r--src/core/hle/kernel/thread.h2
-rw-r--r--src/core/loader/elf.cpp6
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/memory.cpp122
-rw-r--r--src/core/memory.h88
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/core/memory/memory.cpp56
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h2
22 files changed, 71 insertions, 573 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 780a3affe..884c28e20 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -63,8 +63,6 @@ add_library(core STATIC
hle/kernel/hle_ipc.h
hle/kernel/kernel.cpp
hle/kernel/kernel.h
- hle/kernel/memory.cpp
- hle/kernel/memory.h
hle/kernel/mutex.cpp
hle/kernel/mutex.h
hle/kernel/object.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 54fc4170f..9824769cf 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -110,7 +110,7 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file
}
}
- ResultStatus init_result{Init(emu_window, system_mode.first.get())};
+ ResultStatus init_result{Init(emu_window)};
if (init_result != ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
@@ -161,7 +161,7 @@ Cpu& System::CpuCore(size_t core_index) {
return *cpu_cores[core_index];
}
-System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
+System::ResultStatus System::Init(EmuWindow& emu_window) {
LOG_DEBUG(HW_Memory, "initialized OK");
CoreTiming::Init();
@@ -178,7 +178,7 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
telemetry_session = std::make_unique<Core::TelemetrySession>();
service_manager = std::make_shared<Service::SM::ServiceManager>();
- Kernel::Init(system_mode);
+ Kernel::Init();
Service::Init(service_manager);
GDBStub::Init();
diff --git a/src/core/core.h b/src/core/core.h
index f8b6644bb..ed475ac4e 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -189,10 +189,9 @@ private:
* Initialize the emulated system.
* @param emu_window Reference to the host-system window used for video output and keyboard
* input.
- * @param system_mode The system mode.
* @return ResultStatus code, indicating if the operation succeeded.
*/
- ResultStatus Init(EmuWindow& emu_window, u32 system_mode);
+ ResultStatus Init(EmuWindow& emu_window);
/// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 3eb4f465c..1b0cd0abf 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -4,7 +4,6 @@
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
@@ -15,9 +14,7 @@ namespace Kernel {
unsigned int Object::next_object_id;
/// Initialize the kernel
-void Init(u32 system_mode) {
- Kernel::MemoryInit(system_mode);
-
+void Init() {
Kernel::ResourceLimitsInit();
Kernel::ThreadingInit();
Kernel::TimersInit();
@@ -37,7 +34,6 @@ void Shutdown() {
Kernel::TimersShutdown();
Kernel::ResourceLimitsShutdown();
- Kernel::MemoryShutdown();
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 2bc45d7db..131311472 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -9,7 +9,7 @@
namespace Kernel {
/// Initialize the kernel with the specified system mode.
-void Init(u32 system_mode);
+void Init();
/// Shutdown the kernel
void Shutdown();
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
deleted file mode 100644
index a7f3c3c5a..000000000
--- a/src/core/hle/kernel/memory.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-#include <cinttypes>
-#include <memory>
-#include <utility>
-#include <vector>
-#include "common/assert.h"
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "core/hle/kernel/memory.h"
-#include "core/hle/kernel/process.h"
-#include "core/hle/kernel/vm_manager.h"
-#include "core/memory.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace Kernel {
-
-MemoryRegionInfo memory_regions[3];
-
-/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system
-/// memory configuration type.
-static const u32 memory_region_sizes[8][3] = {
- // Old 3DS layouts
- {0x04000000, 0x02C00000, 0x01400000}, // 0
- {/* This appears to be unused. */}, // 1
- {0x06000000, 0x00C00000, 0x01400000}, // 2
- {0x05000000, 0x01C00000, 0x01400000}, // 3
- {0x04800000, 0x02400000, 0x01400000}, // 4
- {0x02000000, 0x04C00000, 0x01400000}, // 5
-
- // New 3DS layouts
- {0x07C00000, 0x06400000, 0x02000000}, // 6
- {0x0B200000, 0x02E00000, 0x02000000}, // 7
-};
-
-void MemoryInit(u32 mem_type) {
- // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead.
- ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!");
- ASSERT(mem_type != 1);
-
- // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with
- // the sizes specified in the memory_region_sizes table.
- VAddr base = 0;
- for (int i = 0; i < 3; ++i) {
- memory_regions[i].base = base;
- memory_regions[i].size = memory_region_sizes[mem_type][i];
- memory_regions[i].used = 0;
- memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>();
- // Reserve enough space for this region of FCRAM.
- // We do not want this block of memory to be relocated when allocating from it.
- memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size);
-
- base += memory_regions[i].size;
- }
-
- // We must've allocated the entire FCRAM by the end
- ASSERT(base == Memory::FCRAM_SIZE);
-}
-
-void MemoryShutdown() {
- for (auto& region : memory_regions) {
- region.base = 0;
- region.size = 0;
- region.used = 0;
- region.linear_heap_memory = nullptr;
- }
-}
-
-MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
- switch (region) {
- case MemoryRegion::APPLICATION:
- return &memory_regions[0];
- case MemoryRegion::SYSTEM:
- return &memory_regions[1];
- case MemoryRegion::BASE:
- return &memory_regions[2];
- default:
- UNREACHABLE();
- }
-}
-
-void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {}
-
-void MapSharedPages(VMManager& address_space) {}
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h
deleted file mode 100644
index 1d05b8871..000000000
--- a/src/core/hle/kernel/memory.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <memory>
-#include <vector>
-
-#include "common/common_types.h"
-
-namespace Kernel {
-
-class VMManager;
-enum class MemoryRegion : u16;
-struct AddressMapping;
-
-struct MemoryRegionInfo {
- u64 base; // Not an address, but offset from start of FCRAM
- u64 size;
- u64 used;
-
- std::shared_ptr<std::vector<u8>> linear_heap_memory;
-};
-
-void MemoryInit(u32 mem_type);
-void MemoryShutdown();
-MemoryRegionInfo* GetMemoryRegion(MemoryRegion region);
-
-void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping);
-void MapSharedPages(VMManager& address_space);
-
-extern MemoryRegionInfo memory_regions[3];
-} // namespace Kernel
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 0c0506085..edf34c5a3 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -8,7 +8,6 @@
#include "common/common_funcs.h"
#include "common/logging/log.h"
#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
@@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
MemoryState::Mapped)
.Unwrap();
- misc_memory_used += stack_size;
- memory_region->used += stack_size;
-
- // Map special address mappings
- MapSharedPages(vm_manager);
- for (const auto& mapping : address_mappings) {
- HandleSpecialMapping(vm_manager, mapping);
- }
vm_manager.LogLayout();
status = ProcessStatus::Running;
@@ -141,37 +132,19 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
}
void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
- memory_region = GetMemoryRegion(flags.memory_region);
-
- auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
- MemoryState memory_state) {
+ const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
+ MemoryState memory_state) {
auto vma = vm_manager
.MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset,
segment.size, memory_state)
.Unwrap();
vm_manager.Reprotect(vma, permissions);
- misc_memory_used += segment.size;
- memory_region->used += segment.size;
};
// Map CodeSet segments
- MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic);
- MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable);
- MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
-}
-
-VAddr Process::GetLinearHeapAreaAddress() const {
- // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of
- // the extra RAM in the n3DS.
- return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR;
-}
-
-VAddr Process::GetLinearHeapBase() const {
- return GetLinearHeapAreaAddress() + memory_region->base;
-}
-
-VAddr Process::GetLinearHeapLimit() const {
- return GetLinearHeapBase() + memory_region->size;
+ MapSegment(module_->CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic);
+ MapSegment(module_->RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable);
+ MapSegment(module_->DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable);
}
ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
@@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
vm_manager.Reprotect(vma, perms);
heap_used = size;
- memory_region->used += size;
return MakeResult<VAddr>(heap_end - size);
}
@@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
return result;
heap_used -= size;
- memory_region->used -= size;
-
- return RESULT_SUCCESS;
-}
-
-ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) {
- UNIMPLEMENTED();
- return {};
-}
-
-ResultCode Process::LinearFree(VAddr target, u32 size) {
- auto& linheap_memory = memory_region->linear_heap_memory;
-
- if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() ||
- target + size < target) {
-
- return ERR_INVALID_ADDRESS;
- }
-
- if (size == 0) {
- return RESULT_SUCCESS;
- }
-
- VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size();
- if (target + size > heap_end) {
- return ERR_INVALID_ADDRESS_STATE;
- }
-
- ResultCode result = vm_manager.UnmapRange(target, size);
- if (result.IsError())
- return result;
-
- linear_heap_used -= size;
- memory_region->used -= size;
-
- if (target + size == heap_end) {
- // End of linear heap has been freed, so check what's the last allocated block in it and
- // reduce the size.
- auto vma = vm_manager.FindVMA(target);
- ASSERT(vma != vm_manager.vma_map.end());
- ASSERT(vma->second.type == VMAType::Free);
- VAddr new_end = vma->second.base;
- if (new_end >= GetLinearHeapBase()) {
- linheap_memory->resize(new_end - GetLinearHeapBase());
- }
- }
return RESULT_SUCCESS;
}
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 1204026be..992689186 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -4,6 +4,7 @@
#pragma once
+#include <array>
#include <bitset>
#include <cstddef>
#include <memory>
@@ -53,9 +54,14 @@ union ProcessFlags {
enum class ProcessStatus { Created, Running, Exited };
class ResourceLimit;
-struct MemoryRegionInfo;
struct CodeSet final : public Object {
+ struct Segment {
+ size_t offset = 0;
+ VAddr addr = 0;
+ u32 size = 0;
+ };
+
static SharedPtr<CodeSet> Create(std::string name);
std::string GetTypeName() const override {
@@ -70,24 +76,38 @@ struct CodeSet final : public Object {
return HANDLE_TYPE;
}
- /// Name of the process
- std::string name;
+ Segment& CodeSegment() {
+ return segments[0];
+ }
- std::shared_ptr<std::vector<u8>> memory;
+ const Segment& CodeSegment() const {
+ return segments[0];
+ }
- struct Segment {
- size_t offset = 0;
- VAddr addr = 0;
- u32 size = 0;
- };
+ Segment& RODataSegment() {
+ return segments[1];
+ }
+
+ const Segment& RODataSegment() const {
+ return segments[1];
+ }
+
+ Segment& DataSegment() {
+ return segments[2];
+ }
+
+ const Segment& DataSegment() const {
+ return segments[2];
+ }
- Segment segments[3];
- Segment& code = segments[0];
- Segment& rodata = segments[1];
- Segment& data = segments[2];
+ std::shared_ptr<std::vector<u8>> memory;
+ std::array<Segment, 3> segments;
VAddr entrypoint;
+ /// Name of the process
+ std::string name;
+
private:
CodeSet();
~CodeSet() override;
@@ -163,12 +183,11 @@ public:
// 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.
std::shared_ptr<std::vector<u8>> heap_memory;
- // The left/right bounds of the address space covered by heap_memory.
- VAddr heap_start = 0, heap_end = 0;
- u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0;
-
- MemoryRegionInfo* memory_region = nullptr;
+ // The left/right bounds of the address space covered by heap_memory.
+ VAddr heap_start = 0;
+ VAddr heap_end = 0;
+ u64 heap_used = 0;
/// The Thread Local Storage area is allocated as processes create threads,
/// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
@@ -179,16 +198,9 @@ public:
std::string name;
- VAddr GetLinearHeapAreaAddress() const;
- VAddr GetLinearHeapBase() const;
- VAddr GetLinearHeapLimit() const;
-
ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
ResultCode HeapFree(VAddr target, u32 size);
- ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms);
- ResultCode LinearFree(VAddr target, u32 size);
-
ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size);
ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index a5b11bd87..21ddc2f7d 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -8,7 +8,6 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/memory.h"
@@ -30,35 +29,17 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
shared_memory->other_permissions = other_permissions;
if (address == 0) {
- // We need to allocate a block from the Linear Heap ourselves.
- // We'll manually allocate some memory from the linear heap in the specified region.
- MemoryRegionInfo* memory_region = GetMemoryRegion(region);
- auto& linheap_memory = memory_region->linear_heap_memory;
-
- ASSERT_MSG(linheap_memory->size() + size <= memory_region->size,
- "Not enough space in region to allocate shared memory!");
-
- shared_memory->backing_block = linheap_memory;
- shared_memory->backing_block_offset = linheap_memory->size();
- // Allocate some memory from the end of the linear heap for this region.
- linheap_memory->insert(linheap_memory->end(), size, 0);
- memory_region->used += size;
-
- shared_memory->linear_heap_phys_address =
- Memory::FCRAM_PADDR + memory_region->base +
- static_cast<PAddr>(shared_memory->backing_block_offset);
-
- // Increase the amount of used linear heap memory for the owner process.
- if (shared_memory->owner_process != nullptr) {
- shared_memory->owner_process->linear_heap_used += size;
- }
+ shared_memory->backing_block = std::make_shared<std::vector<u8>>(size);
+ shared_memory->backing_block_offset = 0;
// Refresh the address mappings for the current process.
if (Core::CurrentProcess() != nullptr) {
- Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
+ Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(
+ shared_memory->backing_block.get());
}
} else {
auto& vm_manager = shared_memory->owner_process->vm_manager;
+
// The memory is already available and mapped in the owner process.
auto vma = vm_manager.FindVMA(address);
ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
@@ -74,6 +55,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
}
shared_memory->base_address = address;
+
return shared_memory;
}
@@ -124,11 +106,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
VAddr target_address = address;
- if (base_address == 0 && target_address == 0) {
- // Calculate the address at which to map the memory block.
- target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value();
- }
-
// Map the memory block into the target process
auto result = target_process->vm_manager.MapMemoryBlock(
target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 8a6f68529..c50fee615 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -111,9 +111,6 @@ public:
SharedPtr<Process> owner_process;
/// Address of shared memory block in the owner process if specified.
VAddr base_address;
- /// Physical address of the shared memory block in the linear heap if no address was specified
- /// during creation.
- PAddr linear_heap_phys_address;
/// Backing memory for this shared memory block.
std::shared_ptr<std::vector<u8>> backing_block;
/// Offset into the backing block for this shared memory.
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index cdb8120f2..b9022feae 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -20,7 +20,6 @@
#include "core/core_timing_util.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
@@ -81,8 +80,8 @@ void Thread::Stop() {
wait_objects.clear();
// Mark the TLS slot in the thread's page as free.
- u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
- u64 tls_slot =
+ const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
+ const u64 tls_slot =
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
}
@@ -336,37 +335,20 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
auto& tls_slots = owner_process->tls_slots;
auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots);
-
if (needs_allocation) {
- // There are no already-allocated pages with free slots, lets allocate a new one.
- // TLS pages are allocated from the BASE region in the linear heap.
- MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE);
- auto& linheap_memory = memory_region->linear_heap_memory;
-
- if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
- LOG_ERROR(Kernel_SVC,
- "Not enough space in region to allocate a new TLS page for thread");
- return ERR_OUT_OF_MEMORY;
- }
-
- size_t offset = linheap_memory->size();
-
- // Allocate some memory from the end of the linear heap for this region.
- linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
- memory_region->used += Memory::PAGE_SIZE;
- owner_process->linear_heap_used += Memory::PAGE_SIZE;
-
tls_slots.emplace_back(0); // The page is completely available at the start
available_page = tls_slots.size() - 1;
available_slot = 0; // Use the first slot in the new page
+ // Allocate some memory from the end of the linear heap for this region.
+ const size_t offset = thread->tls_memory->size();
+ thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0);
+
auto& vm_manager = owner_process->vm_manager;
- vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
+ vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get());
- // Map the page to the current process' address space.
- // TODO(Subv): Find the correct MemoryState for this region.
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
- linheap_memory, offset, Memory::PAGE_SIZE,
+ thread->tls_memory, 0, Memory::PAGE_SIZE,
MemoryState::ThreadLocal);
}
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 146955e13..adc804248 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -265,6 +265,8 @@ public:
private:
Thread();
~Thread() override;
+
+ std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>();
};
/**
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 352938dcb..a7133f5a6 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -311,11 +311,11 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
CodeSet::Segment* codeset_segment;
u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X);
if (permission_flags == (PF_R | PF_X)) {
- codeset_segment = &codeset->code;
+ codeset_segment = &codeset->CodeSegment();
} else if (permission_flags == (PF_R)) {
- codeset_segment = &codeset->rodata;
+ codeset_segment = &codeset->RODataSegment();
} else if (permission_flags == (PF_R | PF_W)) {
- codeset_segment = &codeset->data;
+ codeset_segment = &codeset->DataSegment();
} else {
LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
p->p_flags);
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 7d3ec2a76..dc053cdad 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -159,7 +159,7 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
// Resize program image to include .bss section and page align each section
bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
}
- codeset->data.size += bss_size;
+ codeset->DataSegment().size += bss_size;
program_image.resize(static_cast<u32>(program_image.size()) + bss_size);
// Load codeset for current process
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 06b1b33f4..fee7d58c6 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -127,7 +127,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
// Resize program image to include .bss section and page align each section
bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
}
- codeset->data.size += bss_size;
+ codeset->DataSegment().size += bss_size;
const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)};
program_image.resize(image_size);
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index e753e3436..4b3bb7b31 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -14,7 +14,6 @@
#include "common/swap.h"
#include "core/arm/arm_interface.h"
#include "core/core.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/process.h"
#include "core/hle/lock.h"
#include "core/memory.h"
@@ -24,8 +23,6 @@
namespace Memory {
-static std::array<u8, Memory::VRAM_SIZE> vram;
-
static PageTable* current_page_table = nullptr;
void SetCurrentPageTable(PageTable* page_table) {
@@ -102,22 +99,6 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin
}
/**
- * This function should only be called for virtual addreses with attribute `PageType::Special`.
- */
-static std::set<MemoryHookPointer> GetSpecialHandlers(const PageTable& page_table, VAddr vaddr,
- u64 size) {
- std::set<MemoryHookPointer> result;
- auto interval = boost::icl::discrete_interval<VAddr>::closed(vaddr, vaddr + size - 1);
- auto interval_list = page_table.special_regions.equal_range(interval);
- for (auto it = interval_list.first; it != interval_list.second; ++it) {
- for (const auto& region : it->second) {
- result.insert(region.handler);
- }
- }
- return result;
-}
-
-/**
* Gets a pointer to the exact memory at the virtual address (i.e. not page aligned)
* using a VMA from the current process
*/
@@ -242,10 +223,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) {
return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
}
-bool IsValidPhysicalAddress(const PAddr paddr) {
- return GetPhysicalPointer(paddr) != nullptr;
-}
-
u8* GetPointer(const VAddr vaddr) {
u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
if (page_pointer) {
@@ -274,61 +251,6 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) {
return string;
}
-u8* GetPhysicalPointer(PAddr address) {
- struct MemoryArea {
- PAddr paddr_base;
- u32 size;
- };
-
- static constexpr MemoryArea memory_areas[] = {
- {VRAM_PADDR, VRAM_SIZE},
- {IO_AREA_PADDR, IO_AREA_SIZE},
- {DSP_RAM_PADDR, DSP_RAM_SIZE},
- {FCRAM_PADDR, FCRAM_N3DS_SIZE},
- };
-
- const auto area =
- std::find_if(std::begin(memory_areas), std::end(memory_areas), [&](const auto& area) {
- return address >= area.paddr_base && address < area.paddr_base + area.size;
- });
-
- if (area == std::end(memory_areas)) {
- LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address);
- return nullptr;
- }
-
- if (area->paddr_base == IO_AREA_PADDR) {
- LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address);
- return nullptr;
- }
-
- u64 offset_into_region = address - area->paddr_base;
-
- u8* target_pointer = nullptr;
- switch (area->paddr_base) {
- case VRAM_PADDR:
- target_pointer = vram.data() + offset_into_region;
- break;
- case DSP_RAM_PADDR:
- break;
- case FCRAM_PADDR:
- for (const auto& region : Kernel::memory_regions) {
- if (offset_into_region >= region.base &&
- offset_into_region < region.base + region.size) {
- target_pointer =
- region.linear_heap_memory->data() + offset_into_region - region.base;
- break;
- }
- }
- ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address");
- break;
- default:
- UNREACHABLE();
- }
-
- return target_pointer;
-}
-
void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) {
if (gpu_addr == 0) {
return;
@@ -666,48 +588,4 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) {
CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size);
}
-boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
- if (addr == 0) {
- return 0;
- } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) {
- return addr - VRAM_VADDR + VRAM_PADDR;
- } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) {
- return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR;
- } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) {
- return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR;
- } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) {
- return addr - DSP_RAM_VADDR + DSP_RAM_PADDR;
- } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) {
- return addr - IO_AREA_VADDR + IO_AREA_PADDR;
- }
-
- return boost::none;
-}
-
-PAddr VirtualToPhysicalAddress(const VAddr addr) {
- auto paddr = TryVirtualToPhysicalAddress(addr);
- if (!paddr) {
- LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr);
- // To help with debugging, set bit on address so that it's obviously invalid.
- return addr | 0x80000000;
- }
- return *paddr;
-}
-
-boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
- if (addr == 0) {
- return 0;
- } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
- return addr - VRAM_PADDR + VRAM_VADDR;
- } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
- return addr - FCRAM_PADDR + Core::CurrentProcess()->GetLinearHeapAreaAddress();
- } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
- return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
- } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
- return addr - IO_AREA_PADDR + IO_AREA_VADDR;
- }
-
- return boost::none;
-}
-
} // namespace Memory
diff --git a/src/core/memory.h b/src/core/memory.h
index 8d5d017a4..b5d885b8a 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -6,12 +6,9 @@
#include <array>
#include <cstddef>
-#include <map>
#include <string>
#include <tuple>
-#include <vector>
#include <boost/icl/interval_map.hpp>
-#include <boost/optional.hpp>
#include "common/common_types.h"
#include "core/memory_hook.h"
#include "video_core/memory_manager.h"
@@ -85,40 +82,6 @@ struct PageTable {
std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes;
};
-/// Physical memory regions as seen from the ARM11
-enum : PAddr {
- /// IO register area
- IO_AREA_PADDR = 0x10100000,
- IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB)
- IO_AREA_PADDR_END = IO_AREA_PADDR + IO_AREA_SIZE,
-
- /// MPCore internal memory region
- MPCORE_RAM_PADDR = 0x17E00000,
- MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB)
- MPCORE_RAM_PADDR_END = MPCORE_RAM_PADDR + MPCORE_RAM_SIZE,
-
- /// Video memory
- VRAM_PADDR = 0x18000000,
- VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
- VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
-
- /// DSP memory
- DSP_RAM_PADDR = 0x1FF00000,
- DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
- DSP_RAM_PADDR_END = DSP_RAM_PADDR + DSP_RAM_SIZE,
-
- /// AXI WRAM
- AXI_WRAM_PADDR = 0x1FF80000,
- AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB)
- AXI_WRAM_PADDR_END = AXI_WRAM_PADDR + AXI_WRAM_SIZE,
-
- /// Main FCRAM
- FCRAM_PADDR = 0x20000000,
- FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
- FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
- FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
-};
-
/// Virtual user-space memory regions
enum : VAddr {
/// Where the application text, data and bss reside.
@@ -126,24 +89,6 @@ enum : VAddr {
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
- /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
- /// memory.
- LINEAR_HEAP_VADDR = 0x14000000,
- LINEAR_HEAP_SIZE = 0x08000000,
- LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
-
- /// Maps 1:1 to the IO register area.
- IO_AREA_VADDR = 0x1EC00000,
- IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,
-
- /// Maps 1:1 to VRAM.
- VRAM_VADDR = 0x1F000000,
- VRAM_VADDR_END = VRAM_VADDR + VRAM_SIZE,
-
- /// Maps 1:1 to DSP memory.
- DSP_RAM_VADDR = 0x1FF00000,
- DSP_RAM_VADDR_END = DSP_RAM_VADDR + DSP_RAM_SIZE,
-
/// Read-only page containing kernel and system configuration values.
CONFIG_MEMORY_VADDR = 0x1FF80000,
CONFIG_MEMORY_SIZE = 0x00001000,
@@ -154,13 +99,8 @@ enum : VAddr {
SHARED_PAGE_SIZE = 0x00001000,
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
- /// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
- NEW_LINEAR_HEAP_VADDR = 0x30000000,
- NEW_LINEAR_HEAP_SIZE = 0x10000000,
- NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
-
/// Area where TLS (Thread-Local Storage) buffers are allocated.
- TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END,
+ TLS_AREA_VADDR = 0x40000000,
TLS_ENTRY_SIZE = 0x200,
TLS_AREA_SIZE = 0x10000000,
TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
@@ -205,8 +145,6 @@ bool IsValidVirtualAddress(const VAddr addr);
/// Determines if the given VAddr is a kernel address
bool IsKernelVirtualAddress(const VAddr addr);
-bool IsValidPhysicalAddress(const PAddr addr);
-
u8 Read8(VAddr addr);
u16 Read16(VAddr addr);
u32 Read32(VAddr addr);
@@ -230,30 +168,6 @@ u8* GetPointer(VAddr virtual_address);
std::string ReadCString(VAddr virtual_address, std::size_t max_length);
-/**
- * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
- * address. This should be used by services to translate addresses for use by the hardware.
- */
-boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr);
-
-/**
- * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
- * address. This should be used by services to translate addresses for use by the hardware.
- *
- * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure.
- */
-PAddr VirtualToPhysicalAddress(VAddr addr);
-
-/**
- * Undoes a mapping performed by VirtualToPhysicalAddress().
- */
-boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr);
-
-/**
- * Gets a pointer to the memory region beginning at the specified physical address.
- */
-u8* GetPhysicalPointer(PAddr address);
-
enum class FlushMode {
/// Write back modified surfaces to RAM
Flush,
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 6a0a62ecc..4d74bb395 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -3,7 +3,6 @@ add_executable(tests
core/arm/arm_test_common.cpp
core/arm/arm_test_common.h
core/core_timing.cpp
- core/memory/memory.cpp
glad.cpp
tests.cpp
)
diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp
deleted file mode 100644
index 165496a54..000000000
--- a/src/tests/core/memory/memory.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <catch.hpp>
-#include "core/hle/kernel/memory.h"
-#include "core/hle/kernel/process.h"
-#include "core/memory.h"
-
-TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
- SECTION("these regions should not be mapped on an empty process") {
- auto process = Kernel::Process::Create("");
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
- }
-
- SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
- auto process = Kernel::Process::Create("");
- Kernel::MapSharedPages(process->vm_manager);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
- }
-
- SECTION("special regions should be valid after mapping them") {
- auto process = Kernel::Process::Create("");
- SECTION("VRAM") {
- Kernel::HandleSpecialMapping(process->vm_manager,
- {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
- }
-
- SECTION("IO (Not yet implemented)") {
- Kernel::HandleSpecialMapping(
- process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
- CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
- }
-
- SECTION("DSP") {
- Kernel::HandleSpecialMapping(
- process->vm_manager, {Memory::DSP_RAM_VADDR, Memory::DSP_RAM_SIZE, false, false});
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::DSP_RAM_VADDR) == true);
- }
- }
-
- SECTION("Unmapping a VAddr should make it invalid") {
- auto process = Kernel::Process::Create("");
- Kernel::MapSharedPages(process->vm_manager);
- process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
- }
-}
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index acf067050..68db3c22a 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -412,7 +412,6 @@ public:
}
declarations.AddNewLine();
- unsigned const_buffer_layout = 0;
for (const auto& entry : GetConstBuffersDeclarations()) {
declarations.AddLine("layout(std140) uniform " + entry.GetName());
declarations.AddLine('{');
@@ -420,7 +419,6 @@ public:
"[MAX_CONSTBUFFER_ELEMENTS];");
declarations.AddLine("};");
declarations.AddNewLine();
- ++const_buffer_layout;
}
declarations.AddNewLine();
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 2214c348a..716933a0b 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -118,7 +118,7 @@ public:
return result;
}
- GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) {
+ GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) const {
switch (stage) {
case Maxwell3D::Regs::ShaderStage::Vertex:
return current.vs;