diff options
| author | bunnei <bunneidev@gmail.com> | 2018-08-03 14:07:49 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-03 14:07:49 -0400 | 
| commit | 40e63ede6d2fcb9c4a3f7a65b2bdd25a77835d94 (patch) | |
| tree | 1d81b94e3bdcce384aaa892c1d92a48d725680cf /src/core/hle | |
| parent | 64806a8397b58e2785297c9de2692edd62fc01c2 (diff) | |
| parent | 26de4bb521b1ace7af76eff4f6956cb23ac0d58c (diff) | |
Merge pull request #908 from lioncash/memory
core/memory: Get rid of 3DS leftovers
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory.cpp | 90 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory.h | 34 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 78 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 17 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 63 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 33 | 
9 files changed, 24 insertions, 302 deletions
| 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..5403ceef5 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,17 +132,13 @@ 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 @@ -160,20 +147,6 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {      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; -} -  ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {      if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||          target + size < target) { @@ -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..98d8da35e 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -53,7 +53,6 @@ union ProcessFlags {  enum class ProcessStatus { Created, Running, Exited };  class ResourceLimit; -struct MemoryRegionInfo;  struct CodeSet final : public Object {      static SharedPtr<CodeSet> Create(std::string name); @@ -163,12 +162,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 +177,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..b3ddebb3d 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" @@ -29,51 +28,22 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u      shared_memory->permissions = permissions;      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; -        } - -        // Refresh the address mappings for the current process. -        if (Core::CurrentProcess() != nullptr) { -            Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.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"); -        ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); - -        // The returned VMA might be a bigger one encompassing the desired address. -        auto vma_offset = address - vma->first; -        ASSERT_MSG(vma_offset + size <= vma->second.size, -                   "Shared memory exceeds bounds of mapped block"); - -        shared_memory->backing_block = vma->second.backing_block; -        shared_memory->backing_block_offset = vma->second.offset + vma_offset; -    } +    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"); +    ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); + +    // The returned VMA might be a bigger one encompassing the desired address. +    auto vma_offset = address - vma->first; +    ASSERT_MSG(vma_offset + size <= vma->second.size, +               "Shared memory exceeds bounds of mapped block"); +    shared_memory->backing_block = vma->second.backing_block; +    shared_memory->backing_block_offset = vma->second.offset + vma_offset;      shared_memory->base_address = address; +      return shared_memory;  } @@ -124,11 +94,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..ea9554cbb 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,38 +335,10 @@ 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 - -        auto& vm_manager = owner_process->vm_manager; -        vm_manager.RefreshMemoryBlockMappings(linheap_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, -                                  MemoryState::ThreadLocal);      }      // Mark the slot as used | 
