diff options
| author | 2018-08-02 23:37:44 -0400 | |
|---|---|---|
| committer | 2018-08-03 11:22:47 -0400 | |
| commit | 26de4bb521b1ace7af76eff4f6956cb23ac0d58c (patch) | |
| tree | 904a93d00abf5bde2742499fb3d60a3aa1521820 /src/core/hle/kernel | |
| parent | Merge pull request #892 from lioncash/global (diff) | |
| download | yuzu-26de4bb521b1ace7af76eff4f6956cb23ac0d58c.tar.gz yuzu-26de4bb521b1ace7af76eff4f6956cb23ac0d58c.tar.xz yuzu-26de4bb521b1ace7af76eff4f6956cb23ac0d58c.zip | |
core/memory: Get rid of 3DS leftovers
Removes leftover code from citra that isn't needed.
Diffstat (limited to 'src/core/hle/kernel')
| -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 @@ | |||
| 4 | 4 | ||
| 5 | #include "core/hle/kernel/handle_table.h" | 5 | #include "core/hle/kernel/handle_table.h" |
| 6 | #include "core/hle/kernel/kernel.h" | 6 | #include "core/hle/kernel/kernel.h" |
| 7 | #include "core/hle/kernel/memory.h" | ||
| 8 | #include "core/hle/kernel/process.h" | 7 | #include "core/hle/kernel/process.h" |
| 9 | #include "core/hle/kernel/resource_limit.h" | 8 | #include "core/hle/kernel/resource_limit.h" |
| 10 | #include "core/hle/kernel/thread.h" | 9 | #include "core/hle/kernel/thread.h" |
| @@ -15,9 +14,7 @@ namespace Kernel { | |||
| 15 | unsigned int Object::next_object_id; | 14 | unsigned int Object::next_object_id; |
| 16 | 15 | ||
| 17 | /// Initialize the kernel | 16 | /// Initialize the kernel |
| 18 | void Init(u32 system_mode) { | 17 | void Init() { |
| 19 | Kernel::MemoryInit(system_mode); | ||
| 20 | |||
| 21 | Kernel::ResourceLimitsInit(); | 18 | Kernel::ResourceLimitsInit(); |
| 22 | Kernel::ThreadingInit(); | 19 | Kernel::ThreadingInit(); |
| 23 | Kernel::TimersInit(); | 20 | Kernel::TimersInit(); |
| @@ -37,7 +34,6 @@ void Shutdown() { | |||
| 37 | 34 | ||
| 38 | Kernel::TimersShutdown(); | 35 | Kernel::TimersShutdown(); |
| 39 | Kernel::ResourceLimitsShutdown(); | 36 | Kernel::ResourceLimitsShutdown(); |
| 40 | Kernel::MemoryShutdown(); | ||
| 41 | } | 37 | } |
| 42 | 38 | ||
| 43 | } // namespace Kernel | 39 | } // 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 @@ | |||
| 9 | namespace Kernel { | 9 | namespace Kernel { |
| 10 | 10 | ||
| 11 | /// Initialize the kernel with the specified system mode. | 11 | /// Initialize the kernel with the specified system mode. |
| 12 | void Init(u32 system_mode); | 12 | void Init(); |
| 13 | 13 | ||
| 14 | /// Shutdown the kernel | 14 | /// Shutdown the kernel |
| 15 | void Shutdown(); | 15 | 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 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cinttypes> | ||
| 7 | #include <memory> | ||
| 8 | #include <utility> | ||
| 9 | #include <vector> | ||
| 10 | #include "common/assert.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "common/logging/log.h" | ||
| 13 | #include "core/hle/kernel/memory.h" | ||
| 14 | #include "core/hle/kernel/process.h" | ||
| 15 | #include "core/hle/kernel/vm_manager.h" | ||
| 16 | #include "core/memory.h" | ||
| 17 | |||
| 18 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 19 | |||
| 20 | namespace Kernel { | ||
| 21 | |||
| 22 | MemoryRegionInfo memory_regions[3]; | ||
| 23 | |||
| 24 | /// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system | ||
| 25 | /// memory configuration type. | ||
| 26 | static const u32 memory_region_sizes[8][3] = { | ||
| 27 | // Old 3DS layouts | ||
| 28 | {0x04000000, 0x02C00000, 0x01400000}, // 0 | ||
| 29 | {/* This appears to be unused. */}, // 1 | ||
| 30 | {0x06000000, 0x00C00000, 0x01400000}, // 2 | ||
| 31 | {0x05000000, 0x01C00000, 0x01400000}, // 3 | ||
| 32 | {0x04800000, 0x02400000, 0x01400000}, // 4 | ||
| 33 | {0x02000000, 0x04C00000, 0x01400000}, // 5 | ||
| 34 | |||
| 35 | // New 3DS layouts | ||
| 36 | {0x07C00000, 0x06400000, 0x02000000}, // 6 | ||
| 37 | {0x0B200000, 0x02E00000, 0x02000000}, // 7 | ||
| 38 | }; | ||
| 39 | |||
| 40 | void MemoryInit(u32 mem_type) { | ||
| 41 | // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead. | ||
| 42 | ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!"); | ||
| 43 | ASSERT(mem_type != 1); | ||
| 44 | |||
| 45 | // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with | ||
| 46 | // the sizes specified in the memory_region_sizes table. | ||
| 47 | VAddr base = 0; | ||
| 48 | for (int i = 0; i < 3; ++i) { | ||
| 49 | memory_regions[i].base = base; | ||
| 50 | memory_regions[i].size = memory_region_sizes[mem_type][i]; | ||
| 51 | memory_regions[i].used = 0; | ||
| 52 | memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>(); | ||
| 53 | // Reserve enough space for this region of FCRAM. | ||
| 54 | // We do not want this block of memory to be relocated when allocating from it. | ||
| 55 | memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size); | ||
| 56 | |||
| 57 | base += memory_regions[i].size; | ||
| 58 | } | ||
| 59 | |||
| 60 | // We must've allocated the entire FCRAM by the end | ||
| 61 | ASSERT(base == Memory::FCRAM_SIZE); | ||
| 62 | } | ||
| 63 | |||
| 64 | void MemoryShutdown() { | ||
| 65 | for (auto& region : memory_regions) { | ||
| 66 | region.base = 0; | ||
| 67 | region.size = 0; | ||
| 68 | region.used = 0; | ||
| 69 | region.linear_heap_memory = nullptr; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) { | ||
| 74 | switch (region) { | ||
| 75 | case MemoryRegion::APPLICATION: | ||
| 76 | return &memory_regions[0]; | ||
| 77 | case MemoryRegion::SYSTEM: | ||
| 78 | return &memory_regions[1]; | ||
| 79 | case MemoryRegion::BASE: | ||
| 80 | return &memory_regions[2]; | ||
| 81 | default: | ||
| 82 | UNREACHABLE(); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {} | ||
| 87 | |||
| 88 | void MapSharedPages(VMManager& address_space) {} | ||
| 89 | |||
| 90 | } // 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 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | |||
| 14 | class VMManager; | ||
| 15 | enum class MemoryRegion : u16; | ||
| 16 | struct AddressMapping; | ||
| 17 | |||
| 18 | struct MemoryRegionInfo { | ||
| 19 | u64 base; // Not an address, but offset from start of FCRAM | ||
| 20 | u64 size; | ||
| 21 | u64 used; | ||
| 22 | |||
| 23 | std::shared_ptr<std::vector<u8>> linear_heap_memory; | ||
| 24 | }; | ||
| 25 | |||
| 26 | void MemoryInit(u32 mem_type); | ||
| 27 | void MemoryShutdown(); | ||
| 28 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); | ||
| 29 | |||
| 30 | void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); | ||
| 31 | void MapSharedPages(VMManager& address_space); | ||
| 32 | |||
| 33 | extern MemoryRegionInfo memory_regions[3]; | ||
| 34 | } // 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 @@ | |||
| 8 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "core/hle/kernel/errors.h" | 10 | #include "core/hle/kernel/errors.h" |
| 11 | #include "core/hle/kernel/memory.h" | ||
| 12 | #include "core/hle/kernel/process.h" | 11 | #include "core/hle/kernel/process.h" |
| 13 | #include "core/hle/kernel/resource_limit.h" | 12 | #include "core/hle/kernel/resource_limit.h" |
| 14 | #include "core/hle/kernel/thread.h" | 13 | #include "core/hle/kernel/thread.h" |
| @@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 125 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, | 124 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, |
| 126 | MemoryState::Mapped) | 125 | MemoryState::Mapped) |
| 127 | .Unwrap(); | 126 | .Unwrap(); |
| 128 | misc_memory_used += stack_size; | ||
| 129 | memory_region->used += stack_size; | ||
| 130 | |||
| 131 | // Map special address mappings | ||
| 132 | MapSharedPages(vm_manager); | ||
| 133 | for (const auto& mapping : address_mappings) { | ||
| 134 | HandleSpecialMapping(vm_manager, mapping); | ||
| 135 | } | ||
| 136 | 127 | ||
| 137 | vm_manager.LogLayout(); | 128 | vm_manager.LogLayout(); |
| 138 | status = ProcessStatus::Running; | 129 | status = ProcessStatus::Running; |
| @@ -141,17 +132,13 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 141 | } | 132 | } |
| 142 | 133 | ||
| 143 | void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | 134 | void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { |
| 144 | memory_region = GetMemoryRegion(flags.memory_region); | 135 | const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, |
| 145 | 136 | MemoryState memory_state) { | |
| 146 | auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, | ||
| 147 | MemoryState memory_state) { | ||
| 148 | auto vma = vm_manager | 137 | auto vma = vm_manager |
| 149 | .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, | 138 | .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, |
| 150 | segment.size, memory_state) | 139 | segment.size, memory_state) |
| 151 | .Unwrap(); | 140 | .Unwrap(); |
| 152 | vm_manager.Reprotect(vma, permissions); | 141 | vm_manager.Reprotect(vma, permissions); |
| 153 | misc_memory_used += segment.size; | ||
| 154 | memory_region->used += segment.size; | ||
| 155 | }; | 142 | }; |
| 156 | 143 | ||
| 157 | // Map CodeSet segments | 144 | // Map CodeSet segments |
| @@ -160,20 +147,6 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | |||
| 160 | MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable); | 147 | MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable); |
| 161 | } | 148 | } |
| 162 | 149 | ||
| 163 | VAddr Process::GetLinearHeapAreaAddress() const { | ||
| 164 | // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of | ||
| 165 | // the extra RAM in the n3DS. | ||
| 166 | return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR; | ||
| 167 | } | ||
| 168 | |||
| 169 | VAddr Process::GetLinearHeapBase() const { | ||
| 170 | return GetLinearHeapAreaAddress() + memory_region->base; | ||
| 171 | } | ||
| 172 | |||
| 173 | VAddr Process::GetLinearHeapLimit() const { | ||
| 174 | return GetLinearHeapBase() + memory_region->size; | ||
| 175 | } | ||
| 176 | |||
| 177 | ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { | 150 | ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { |
| 178 | if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || | 151 | if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || |
| 179 | target + size < target) { | 152 | target + size < target) { |
| @@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per | |||
| 206 | vm_manager.Reprotect(vma, perms); | 179 | vm_manager.Reprotect(vma, perms); |
| 207 | 180 | ||
| 208 | heap_used = size; | 181 | heap_used = size; |
| 209 | memory_region->used += size; | ||
| 210 | 182 | ||
| 211 | return MakeResult<VAddr>(heap_end - size); | 183 | return MakeResult<VAddr>(heap_end - size); |
| 212 | } | 184 | } |
| @@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { | |||
| 226 | return result; | 198 | return result; |
| 227 | 199 | ||
| 228 | heap_used -= size; | 200 | heap_used -= size; |
| 229 | memory_region->used -= size; | ||
| 230 | |||
| 231 | return RESULT_SUCCESS; | ||
| 232 | } | ||
| 233 | |||
| 234 | ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) { | ||
| 235 | UNIMPLEMENTED(); | ||
| 236 | return {}; | ||
| 237 | } | ||
| 238 | |||
| 239 | ResultCode Process::LinearFree(VAddr target, u32 size) { | ||
| 240 | auto& linheap_memory = memory_region->linear_heap_memory; | ||
| 241 | |||
| 242 | if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() || | ||
| 243 | target + size < target) { | ||
| 244 | |||
| 245 | return ERR_INVALID_ADDRESS; | ||
| 246 | } | ||
| 247 | |||
| 248 | if (size == 0) { | ||
| 249 | return RESULT_SUCCESS; | ||
| 250 | } | ||
| 251 | |||
| 252 | VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size(); | ||
| 253 | if (target + size > heap_end) { | ||
| 254 | return ERR_INVALID_ADDRESS_STATE; | ||
| 255 | } | ||
| 256 | |||
| 257 | ResultCode result = vm_manager.UnmapRange(target, size); | ||
| 258 | if (result.IsError()) | ||
| 259 | return result; | ||
| 260 | |||
| 261 | linear_heap_used -= size; | ||
| 262 | memory_region->used -= size; | ||
| 263 | |||
| 264 | if (target + size == heap_end) { | ||
| 265 | // End of linear heap has been freed, so check what's the last allocated block in it and | ||
| 266 | // reduce the size. | ||
| 267 | auto vma = vm_manager.FindVMA(target); | ||
| 268 | ASSERT(vma != vm_manager.vma_map.end()); | ||
| 269 | ASSERT(vma->second.type == VMAType::Free); | ||
| 270 | VAddr new_end = vma->second.base; | ||
| 271 | if (new_end >= GetLinearHeapBase()) { | ||
| 272 | linheap_memory->resize(new_end - GetLinearHeapBase()); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | 201 | ||
| 276 | return RESULT_SUCCESS; | 202 | return RESULT_SUCCESS; |
| 277 | } | 203 | } |
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 { | |||
| 53 | enum class ProcessStatus { Created, Running, Exited }; | 53 | enum class ProcessStatus { Created, Running, Exited }; |
| 54 | 54 | ||
| 55 | class ResourceLimit; | 55 | class ResourceLimit; |
| 56 | struct MemoryRegionInfo; | ||
| 57 | 56 | ||
| 58 | struct CodeSet final : public Object { | 57 | struct CodeSet final : public Object { |
| 59 | static SharedPtr<CodeSet> Create(std::string name); | 58 | static SharedPtr<CodeSet> Create(std::string name); |
| @@ -163,12 +162,11 @@ public: | |||
| 163 | // This makes deallocation and reallocation of holes fast and keeps process memory contiguous | 162 | // This makes deallocation and reallocation of holes fast and keeps process memory contiguous |
| 164 | // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. | 163 | // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. |
| 165 | std::shared_ptr<std::vector<u8>> heap_memory; | 164 | std::shared_ptr<std::vector<u8>> heap_memory; |
| 166 | // The left/right bounds of the address space covered by heap_memory. | ||
| 167 | VAddr heap_start = 0, heap_end = 0; | ||
| 168 | |||
| 169 | u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0; | ||
| 170 | 165 | ||
| 171 | MemoryRegionInfo* memory_region = nullptr; | 166 | // The left/right bounds of the address space covered by heap_memory. |
| 167 | VAddr heap_start = 0; | ||
| 168 | VAddr heap_end = 0; | ||
| 169 | u64 heap_used = 0; | ||
| 172 | 170 | ||
| 173 | /// The Thread Local Storage area is allocated as processes create threads, | 171 | /// The Thread Local Storage area is allocated as processes create threads, |
| 174 | /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part | 172 | /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part |
| @@ -179,16 +177,9 @@ public: | |||
| 179 | 177 | ||
| 180 | std::string name; | 178 | std::string name; |
| 181 | 179 | ||
| 182 | VAddr GetLinearHeapAreaAddress() const; | ||
| 183 | VAddr GetLinearHeapBase() const; | ||
| 184 | VAddr GetLinearHeapLimit() const; | ||
| 185 | |||
| 186 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); | 180 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); |
| 187 | ResultCode HeapFree(VAddr target, u32 size); | 181 | ResultCode HeapFree(VAddr target, u32 size); |
| 188 | 182 | ||
| 189 | ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms); | ||
| 190 | ResultCode LinearFree(VAddr target, u32 size); | ||
| 191 | |||
| 192 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); | 183 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); |
| 193 | 184 | ||
| 194 | ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); | 185 | 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 @@ | |||
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/errors.h" | 10 | #include "core/hle/kernel/errors.h" |
| 11 | #include "core/hle/kernel/memory.h" | ||
| 12 | #include "core/hle/kernel/shared_memory.h" | 11 | #include "core/hle/kernel/shared_memory.h" |
| 13 | #include "core/memory.h" | 12 | #include "core/memory.h" |
| 14 | 13 | ||
| @@ -29,51 +28,22 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u | |||
| 29 | shared_memory->permissions = permissions; | 28 | shared_memory->permissions = permissions; |
| 30 | shared_memory->other_permissions = other_permissions; | 29 | shared_memory->other_permissions = other_permissions; |
| 31 | 30 | ||
| 32 | if (address == 0) { | 31 | auto& vm_manager = shared_memory->owner_process->vm_manager; |
| 33 | // We need to allocate a block from the Linear Heap ourselves. | 32 | |
| 34 | // We'll manually allocate some memory from the linear heap in the specified region. | 33 | // The memory is already available and mapped in the owner process. |
| 35 | MemoryRegionInfo* memory_region = GetMemoryRegion(region); | 34 | auto vma = vm_manager.FindVMA(address); |
| 36 | auto& linheap_memory = memory_region->linear_heap_memory; | 35 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); |
| 37 | 36 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); | |
| 38 | ASSERT_MSG(linheap_memory->size() + size <= memory_region->size, | 37 | |
| 39 | "Not enough space in region to allocate shared memory!"); | 38 | // The returned VMA might be a bigger one encompassing the desired address. |
| 40 | 39 | auto vma_offset = address - vma->first; | |
| 41 | shared_memory->backing_block = linheap_memory; | 40 | ASSERT_MSG(vma_offset + size <= vma->second.size, |
| 42 | shared_memory->backing_block_offset = linheap_memory->size(); | 41 | "Shared memory exceeds bounds of mapped block"); |
| 43 | // Allocate some memory from the end of the linear heap for this region. | ||
| 44 | linheap_memory->insert(linheap_memory->end(), size, 0); | ||
| 45 | memory_region->used += size; | ||
| 46 | |||
| 47 | shared_memory->linear_heap_phys_address = | ||
| 48 | Memory::FCRAM_PADDR + memory_region->base + | ||
| 49 | static_cast<PAddr>(shared_memory->backing_block_offset); | ||
| 50 | |||
| 51 | // Increase the amount of used linear heap memory for the owner process. | ||
| 52 | if (shared_memory->owner_process != nullptr) { | ||
| 53 | shared_memory->owner_process->linear_heap_used += size; | ||
| 54 | } | ||
| 55 | |||
| 56 | // Refresh the address mappings for the current process. | ||
| 57 | if (Core::CurrentProcess() != nullptr) { | ||
| 58 | Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); | ||
| 59 | } | ||
| 60 | } else { | ||
| 61 | auto& vm_manager = shared_memory->owner_process->vm_manager; | ||
| 62 | // The memory is already available and mapped in the owner process. | ||
| 63 | auto vma = vm_manager.FindVMA(address); | ||
| 64 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); | ||
| 65 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); | ||
| 66 | |||
| 67 | // The returned VMA might be a bigger one encompassing the desired address. | ||
| 68 | auto vma_offset = address - vma->first; | ||
| 69 | ASSERT_MSG(vma_offset + size <= vma->second.size, | ||
| 70 | "Shared memory exceeds bounds of mapped block"); | ||
| 71 | |||
| 72 | shared_memory->backing_block = vma->second.backing_block; | ||
| 73 | shared_memory->backing_block_offset = vma->second.offset + vma_offset; | ||
| 74 | } | ||
| 75 | 42 | ||
| 43 | shared_memory->backing_block = vma->second.backing_block; | ||
| 44 | shared_memory->backing_block_offset = vma->second.offset + vma_offset; | ||
| 76 | shared_memory->base_address = address; | 45 | shared_memory->base_address = address; |
| 46 | |||
| 77 | return shared_memory; | 47 | return shared_memory; |
| 78 | } | 48 | } |
| 79 | 49 | ||
| @@ -124,11 +94,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi | |||
| 124 | 94 | ||
| 125 | VAddr target_address = address; | 95 | VAddr target_address = address; |
| 126 | 96 | ||
| 127 | if (base_address == 0 && target_address == 0) { | ||
| 128 | // Calculate the address at which to map the memory block. | ||
| 129 | target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value(); | ||
| 130 | } | ||
| 131 | |||
| 132 | // Map the memory block into the target process | 97 | // Map the memory block into the target process |
| 133 | auto result = target_process->vm_manager.MapMemoryBlock( | 98 | auto result = target_process->vm_manager.MapMemoryBlock( |
| 134 | target_address, backing_block, backing_block_offset, size, MemoryState::Shared); | 99 | 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: | |||
| 111 | SharedPtr<Process> owner_process; | 111 | SharedPtr<Process> owner_process; |
| 112 | /// Address of shared memory block in the owner process if specified. | 112 | /// Address of shared memory block in the owner process if specified. |
| 113 | VAddr base_address; | 113 | VAddr base_address; |
| 114 | /// Physical address of the shared memory block in the linear heap if no address was specified | ||
| 115 | /// during creation. | ||
| 116 | PAddr linear_heap_phys_address; | ||
| 117 | /// Backing memory for this shared memory block. | 114 | /// Backing memory for this shared memory block. |
| 118 | std::shared_ptr<std::vector<u8>> backing_block; | 115 | std::shared_ptr<std::vector<u8>> backing_block; |
| 119 | /// Offset into the backing block for this shared memory. | 116 | /// 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 @@ | |||
| 20 | #include "core/core_timing_util.h" | 20 | #include "core/core_timing_util.h" |
| 21 | #include "core/hle/kernel/errors.h" | 21 | #include "core/hle/kernel/errors.h" |
| 22 | #include "core/hle/kernel/handle_table.h" | 22 | #include "core/hle/kernel/handle_table.h" |
| 23 | #include "core/hle/kernel/memory.h" | ||
| 24 | #include "core/hle/kernel/object.h" | 23 | #include "core/hle/kernel/object.h" |
| 25 | #include "core/hle/kernel/process.h" | 24 | #include "core/hle/kernel/process.h" |
| 26 | #include "core/hle/kernel/thread.h" | 25 | #include "core/hle/kernel/thread.h" |
| @@ -81,8 +80,8 @@ void Thread::Stop() { | |||
| 81 | wait_objects.clear(); | 80 | wait_objects.clear(); |
| 82 | 81 | ||
| 83 | // Mark the TLS slot in the thread's page as free. | 82 | // Mark the TLS slot in the thread's page as free. |
| 84 | u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; | 83 | const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; |
| 85 | u64 tls_slot = | 84 | const u64 tls_slot = |
| 86 | ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; | 85 | ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; |
| 87 | Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); | 86 | Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); |
| 88 | } | 87 | } |
| @@ -336,38 +335,10 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 336 | auto& tls_slots = owner_process->tls_slots; | 335 | auto& tls_slots = owner_process->tls_slots; |
| 337 | 336 | ||
| 338 | auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); | 337 | auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); |
| 339 | |||
| 340 | if (needs_allocation) { | 338 | if (needs_allocation) { |
| 341 | // There are no already-allocated pages with free slots, lets allocate a new one. | ||
| 342 | // TLS pages are allocated from the BASE region in the linear heap. | ||
| 343 | MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE); | ||
| 344 | auto& linheap_memory = memory_region->linear_heap_memory; | ||
| 345 | |||
| 346 | if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { | ||
| 347 | LOG_ERROR(Kernel_SVC, | ||
| 348 | "Not enough space in region to allocate a new TLS page for thread"); | ||
| 349 | return ERR_OUT_OF_MEMORY; | ||
| 350 | } | ||
| 351 | |||
| 352 | size_t offset = linheap_memory->size(); | ||
| 353 | |||
| 354 | // Allocate some memory from the end of the linear heap for this region. | ||
| 355 | linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0); | ||
| 356 | memory_region->used += Memory::PAGE_SIZE; | ||
| 357 | owner_process->linear_heap_used += Memory::PAGE_SIZE; | ||
| 358 | |||
| 359 | tls_slots.emplace_back(0); // The page is completely available at the start | 339 | tls_slots.emplace_back(0); // The page is completely available at the start |
| 360 | available_page = tls_slots.size() - 1; | 340 | available_page = tls_slots.size() - 1; |
| 361 | available_slot = 0; // Use the first slot in the new page | 341 | available_slot = 0; // Use the first slot in the new page |
| 362 | |||
| 363 | auto& vm_manager = owner_process->vm_manager; | ||
| 364 | vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); | ||
| 365 | |||
| 366 | // Map the page to the current process' address space. | ||
| 367 | // TODO(Subv): Find the correct MemoryState for this region. | ||
| 368 | vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, | ||
| 369 | linheap_memory, offset, Memory::PAGE_SIZE, | ||
| 370 | MemoryState::ThreadLocal); | ||
| 371 | } | 342 | } |
| 372 | 343 | ||
| 373 | // Mark the slot as used | 344 | // Mark the slot as used |