diff options
| author | 2017-05-14 13:52:40 -0700 | |
|---|---|---|
| committer | 2017-05-14 13:52:40 -0700 | |
| commit | 180587bb8bd18feeb81028007556276ef4ecaafd (patch) | |
| tree | 5939bfa2c92ced9b30ade0b725ace7b7dce3d040 /src | |
| parent | Merge pull request #2695 from JayFoxRox/gs-regs (diff) | |
| parent | Kernel: Map special regions according to ExHeader (diff) | |
| download | yuzu-180587bb8bd18feeb81028007556276ef4ecaafd.tar.gz yuzu-180587bb8bd18feeb81028007556276ef4ecaafd.tar.xz yuzu-180587bb8bd18feeb81028007556276ef4ecaafd.zip | |
Merge pull request #2687 from yuriks/address-mappings
Kernel: Map special regions according to ExHeader
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/audio_core.cpp | 19 | ||||
| -rw-r--r-- | src/audio_core/audio_core.h | 13 | ||||
| -rw-r--r-- | src/audio_core/hle/dsp.cpp | 14 | ||||
| -rw-r--r-- | src/audio_core/hle/dsp.h | 21 | ||||
| -rw-r--r-- | src/core/core.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory.cpp | 112 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory.h | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 23 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 2 | ||||
| -rw-r--r-- | src/core/memory.cpp | 8 | ||||
| -rw-r--r-- | src/core/memory.h | 10 |
11 files changed, 157 insertions, 80 deletions
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp index 84f9c03a7..9c2e6ed88 100644 --- a/src/audio_core/audio_core.cpp +++ b/src/audio_core/audio_core.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | ||
| 5 | #include <memory> | 6 | #include <memory> |
| 6 | #include <string> | 7 | #include <string> |
| 7 | #include "audio_core/audio_core.h" | 8 | #include "audio_core/audio_core.h" |
| @@ -10,8 +11,8 @@ | |||
| 10 | #include "audio_core/null_sink.h" | 11 | #include "audio_core/null_sink.h" |
| 11 | #include "audio_core/sink.h" | 12 | #include "audio_core/sink.h" |
| 12 | #include "audio_core/sink_details.h" | 13 | #include "audio_core/sink_details.h" |
| 14 | #include "common/common_types.h" | ||
| 13 | #include "core/core_timing.h" | 15 | #include "core/core_timing.h" |
| 14 | #include "core/hle/kernel/vm_manager.h" | ||
| 15 | #include "core/hle/service/dsp_dsp.h" | 16 | #include "core/hle/service/dsp_dsp.h" |
| 16 | 17 | ||
| 17 | namespace AudioCore { | 18 | namespace AudioCore { |
| @@ -39,20 +40,8 @@ void Init() { | |||
| 39 | CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event); | 40 | CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | void AddAddressSpace(Kernel::VMManager& address_space) { | 43 | std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() { |
| 43 | auto r0_vma = address_space | 44 | return DSP::HLE::g_dsp_memory.raw_memory; |
| 44 | .MapBackingMemory(DSP::HLE::region0_base, | ||
| 45 | reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), | ||
| 46 | sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO) | ||
| 47 | .MoveFrom(); | ||
| 48 | address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite); | ||
| 49 | |||
| 50 | auto r1_vma = address_space | ||
| 51 | .MapBackingMemory(DSP::HLE::region1_base, | ||
| 52 | reinterpret_cast<u8*>(&DSP::HLE::g_regions[1]), | ||
| 53 | sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO) | ||
| 54 | .MoveFrom(); | ||
| 55 | address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite); | ||
| 56 | } | 45 | } |
| 57 | 46 | ||
| 58 | void SelectSink(std::string sink_id) { | 47 | void SelectSink(std::string sink_id) { |
diff --git a/src/audio_core/audio_core.h b/src/audio_core/audio_core.h index 0edf6dd15..ab323ce1f 100644 --- a/src/audio_core/audio_core.h +++ b/src/audio_core/audio_core.h | |||
| @@ -4,11 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <string> | 8 | #include <string> |
| 8 | 9 | #include "common/common_types.h" | |
| 9 | namespace Kernel { | 10 | #include "core/memory.h" |
| 10 | class VMManager; | ||
| 11 | } | ||
| 12 | 11 | ||
| 13 | namespace AudioCore { | 12 | namespace AudioCore { |
| 14 | 13 | ||
| @@ -17,8 +16,8 @@ constexpr int native_sample_rate = 32728; ///< 32kHz | |||
| 17 | /// Initialise Audio Core | 16 | /// Initialise Audio Core |
| 18 | void Init(); | 17 | void Init(); |
| 19 | 18 | ||
| 20 | /// Add DSP address spaces to a Process. | 19 | /// Returns a reference to the array backing DSP memory |
| 21 | void AddAddressSpace(Kernel::VMManager& vm_manager); | 20 | std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory(); |
| 22 | 21 | ||
| 23 | /// Select the sink to use based on sink id. | 22 | /// Select the sink to use based on sink id. |
| 24 | void SelectSink(std::string sink_id); | 23 | void SelectSink(std::string sink_id); |
| @@ -29,4 +28,4 @@ void EnableStretching(bool enable); | |||
| 29 | /// Shutdown Audio Core | 28 | /// Shutdown Audio Core |
| 30 | void Shutdown(); | 29 | void Shutdown(); |
| 31 | 30 | ||
| 32 | } // namespace | 31 | } // namespace AudioCore |
diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp index 31421fdc6..260b182ed 100644 --- a/src/audio_core/hle/dsp.cpp +++ b/src/audio_core/hle/dsp.cpp | |||
| @@ -16,31 +16,33 @@ namespace HLE { | |||
| 16 | 16 | ||
| 17 | // Region management | 17 | // Region management |
| 18 | 18 | ||
| 19 | std::array<SharedMemory, 2> g_regions; | 19 | DspMemory g_dsp_memory; |
| 20 | 20 | ||
| 21 | static size_t CurrentRegionIndex() { | 21 | static size_t CurrentRegionIndex() { |
| 22 | // The region with the higher frame counter is chosen unless there is wraparound. | 22 | // The region with the higher frame counter is chosen unless there is wraparound. |
| 23 | // This function only returns a 0 or 1. | 23 | // This function only returns a 0 or 1. |
| 24 | u16 frame_counter_0 = g_dsp_memory.region_0.frame_counter; | ||
| 25 | u16 frame_counter_1 = g_dsp_memory.region_1.frame_counter; | ||
| 24 | 26 | ||
| 25 | if (g_regions[0].frame_counter == 0xFFFFu && g_regions[1].frame_counter != 0xFFFEu) { | 27 | if (frame_counter_0 == 0xFFFFu && frame_counter_1 != 0xFFFEu) { |
| 26 | // Wraparound has occurred. | 28 | // Wraparound has occurred. |
| 27 | return 1; | 29 | return 1; |
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | if (g_regions[1].frame_counter == 0xFFFFu && g_regions[0].frame_counter != 0xFFFEu) { | 32 | if (frame_counter_1 == 0xFFFFu && frame_counter_0 != 0xFFFEu) { |
| 31 | // Wraparound has occurred. | 33 | // Wraparound has occurred. |
| 32 | return 0; | 34 | return 0; |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | return (g_regions[0].frame_counter > g_regions[1].frame_counter) ? 0 : 1; | 37 | return (frame_counter_0 > frame_counter_1) ? 0 : 1; |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | static SharedMemory& ReadRegion() { | 40 | static SharedMemory& ReadRegion() { |
| 39 | return g_regions[CurrentRegionIndex()]; | 41 | return CurrentRegionIndex() == 0 ? g_dsp_memory.region_0 : g_dsp_memory.region_1; |
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | static SharedMemory& WriteRegion() { | 44 | static SharedMemory& WriteRegion() { |
| 43 | return g_regions[1 - CurrentRegionIndex()]; | 45 | return CurrentRegionIndex() != 0 ? g_dsp_memory.region_0 : g_dsp_memory.region_1; |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | // Audio processing and mixing | 48 | // Audio processing and mixing |
diff --git a/src/audio_core/hle/dsp.h b/src/audio_core/hle/dsp.h index 0a0f60ac1..94ce48863 100644 --- a/src/audio_core/hle/dsp.h +++ b/src/audio_core/hle/dsp.h | |||
| @@ -31,8 +31,8 @@ namespace HLE { | |||
| 31 | // double-buffer. The frame counter is located as the very last u16 of each region and is | 31 | // double-buffer. The frame counter is located as the very last u16 of each region and is |
| 32 | // incremented each audio tick. | 32 | // incremented each audio tick. |
| 33 | 33 | ||
| 34 | constexpr VAddr region0_base = 0x1FF50000; | 34 | constexpr u32 region0_offset = 0x50000; |
| 35 | constexpr VAddr region1_base = 0x1FF70000; | 35 | constexpr u32 region1_offset = 0x70000; |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | * The DSP is native 16-bit. The DSP also appears to be big-endian. When reading 32-bit numbers from | 38 | * The DSP is native 16-bit. The DSP also appears to be big-endian. When reading 32-bit numbers from |
| @@ -512,7 +512,22 @@ struct SharedMemory { | |||
| 512 | }; | 512 | }; |
| 513 | ASSERT_DSP_STRUCT(SharedMemory, 0x8000); | 513 | ASSERT_DSP_STRUCT(SharedMemory, 0x8000); |
| 514 | 514 | ||
| 515 | extern std::array<SharedMemory, 2> g_regions; | 515 | union DspMemory { |
| 516 | std::array<u8, 0x80000> raw_memory; | ||
| 517 | struct { | ||
| 518 | u8 unused_0[0x50000]; | ||
| 519 | SharedMemory region_0; | ||
| 520 | u8 unused_1[0x18000]; | ||
| 521 | SharedMemory region_1; | ||
| 522 | u8 unused_2[0x8000]; | ||
| 523 | }; | ||
| 524 | }; | ||
| 525 | static_assert(offsetof(DspMemory, region_0) == region0_offset, | ||
| 526 | "DSP region 0 is at the wrong offset"); | ||
| 527 | static_assert(offsetof(DspMemory, region_1) == region1_offset, | ||
| 528 | "DSP region 1 is at the wrong offset"); | ||
| 529 | |||
| 530 | extern DspMemory g_dsp_memory; | ||
| 516 | 531 | ||
| 517 | // Structures must have an offset that is a multiple of two. | 532 | // Structures must have an offset that is a multiple of two. |
| 518 | static_assert(offsetof(SharedMemory, frame_counter) % 2 == 0, | 533 | static_assert(offsetof(SharedMemory, frame_counter) % 2 == 0, |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 140ff6451..881f1e93c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -13,11 +13,11 @@ | |||
| 13 | #include "core/core_timing.h" | 13 | #include "core/core_timing.h" |
| 14 | #include "core/gdbstub/gdbstub.h" | 14 | #include "core/gdbstub/gdbstub.h" |
| 15 | #include "core/hle/kernel/kernel.h" | 15 | #include "core/hle/kernel/kernel.h" |
| 16 | #include "core/hle/kernel/memory.h" | ||
| 17 | #include "core/hle/kernel/thread.h" | 16 | #include "core/hle/kernel/thread.h" |
| 18 | #include "core/hle/service/service.h" | 17 | #include "core/hle/service/service.h" |
| 19 | #include "core/hw/hw.h" | 18 | #include "core/hw/hw.h" |
| 20 | #include "core/loader/loader.h" | 19 | #include "core/loader/loader.h" |
| 20 | #include "core/memory_setup.h" | ||
| 21 | #include "core/settings.h" | 21 | #include "core/settings.h" |
| 22 | #include "video_core/video_core.h" | 22 | #include "video_core/video_core.h" |
| 23 | 23 | ||
| @@ -123,7 +123,8 @@ void System::Reschedule() { | |||
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { | 125 | System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { |
| 126 | Memory::Init(); | 126 | Memory::InitMemoryMap(); |
| 127 | LOG_DEBUG(HW_Memory, "initialized OK"); | ||
| 127 | 128 | ||
| 128 | if (Settings::values.use_cpu_jit) { | 129 | if (Settings::values.use_cpu_jit) { |
| 129 | cpu_core = std::make_unique<ARM_Dynarmic>(USER32MODE); | 130 | cpu_core = std::make_unique<ARM_Dynarmic>(USER32MODE); |
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index 33c165197..8250a90b5 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp | |||
| @@ -2,11 +2,13 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cinttypes> | ||
| 5 | #include <map> | 6 | #include <map> |
| 6 | #include <memory> | 7 | #include <memory> |
| 7 | #include <utility> | 8 | #include <utility> |
| 8 | #include <vector> | 9 | #include <vector> |
| 9 | #include "audio_core/audio_core.h" | 10 | #include "audio_core/audio_core.h" |
| 11 | #include "common/assert.h" | ||
| 10 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 11 | #include "common/logging/log.h" | 13 | #include "common/logging/log.h" |
| 12 | #include "core/hle/config_mem.h" | 14 | #include "core/hle/config_mem.h" |
| @@ -92,52 +94,96 @@ MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) { | |||
| 92 | UNREACHABLE(); | 94 | UNREACHABLE(); |
| 93 | } | 95 | } |
| 94 | } | 96 | } |
| 95 | } | ||
| 96 | |||
| 97 | namespace Memory { | ||
| 98 | 97 | ||
| 99 | namespace { | 98 | std::array<u8, Memory::VRAM_SIZE> vram; |
| 99 | std::array<u8, Memory::N3DS_EXTRA_RAM_SIZE> n3ds_extra_ram; | ||
| 100 | |||
| 101 | void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) { | ||
| 102 | using namespace Memory; | ||
| 103 | |||
| 104 | struct MemoryArea { | ||
| 105 | VAddr vaddr_base; | ||
| 106 | PAddr paddr_base; | ||
| 107 | u32 size; | ||
| 108 | }; | ||
| 109 | |||
| 110 | // The order of entries in this array is important. The VRAM and IO VAddr ranges overlap, and | ||
| 111 | // VRAM must be tried first. | ||
| 112 | static constexpr MemoryArea memory_areas[] = { | ||
| 113 | {VRAM_VADDR, VRAM_PADDR, VRAM_SIZE}, | ||
| 114 | {IO_AREA_VADDR, IO_AREA_PADDR, IO_AREA_SIZE}, | ||
| 115 | {DSP_RAM_VADDR, DSP_RAM_PADDR, DSP_RAM_SIZE}, | ||
| 116 | {N3DS_EXTRA_RAM_VADDR, N3DS_EXTRA_RAM_PADDR, N3DS_EXTRA_RAM_SIZE - 0x20000}, | ||
| 117 | }; | ||
| 118 | |||
| 119 | VAddr mapping_limit = mapping.address + mapping.size; | ||
| 120 | if (mapping_limit < mapping.address) { | ||
| 121 | LOG_CRITICAL(Loader, "Mapping size overflowed: address=0x%08" PRIX32 " size=0x%" PRIX32, | ||
| 122 | mapping.address, mapping.size); | ||
| 123 | return; | ||
| 124 | } | ||
| 100 | 125 | ||
| 101 | struct MemoryArea { | 126 | auto area = |
| 102 | u32 base; | 127 | std::find_if(std::begin(memory_areas), std::end(memory_areas), [&](const auto& area) { |
| 103 | u32 size; | 128 | return mapping.address >= area.vaddr_base && |
| 104 | const char* name; | 129 | mapping_limit <= area.vaddr_base + area.size; |
| 105 | }; | 130 | }); |
| 131 | if (area == std::end(memory_areas)) { | ||
| 132 | LOG_ERROR(Loader, "Unhandled special mapping: address=0x%08" PRIX32 " size=0x%" PRIX32 | ||
| 133 | " read_only=%d unk_flag=%d", | ||
| 134 | mapping.address, mapping.size, mapping.read_only, mapping.unk_flag); | ||
| 135 | return; | ||
| 136 | } | ||
| 106 | 137 | ||
| 107 | // We don't declare the IO regions in here since its handled by other means. | 138 | u32 offset_into_region = mapping.address - area->vaddr_base; |
| 108 | static MemoryArea memory_areas[] = { | 139 | if (area->paddr_base == IO_AREA_PADDR) { |
| 109 | {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM) | 140 | LOG_ERROR(Loader, "MMIO mappings are not supported yet. phys_addr=0x%08" PRIX32, |
| 110 | }; | 141 | area->paddr_base + offset_into_region); |
| 111 | } | 142 | return; |
| 143 | } | ||
| 112 | 144 | ||
| 113 | void Init() { | 145 | // TODO(yuriks): Use GetPhysicalPointer when that becomes independent of the virtual |
| 114 | InitMemoryMap(); | 146 | // mappings. |
| 115 | LOG_DEBUG(HW_Memory, "initialized OK"); | 147 | u8* target_pointer = nullptr; |
| 116 | } | 148 | switch (area->paddr_base) { |
| 149 | case VRAM_PADDR: | ||
| 150 | target_pointer = vram.data(); | ||
| 151 | break; | ||
| 152 | case DSP_RAM_PADDR: | ||
| 153 | target_pointer = AudioCore::GetDspMemory().data(); | ||
| 154 | break; | ||
| 155 | case N3DS_EXTRA_RAM_PADDR: | ||
| 156 | target_pointer = n3ds_extra_ram.data(); | ||
| 157 | break; | ||
| 158 | default: | ||
| 159 | UNREACHABLE(); | ||
| 160 | } | ||
| 117 | 161 | ||
| 118 | void InitLegacyAddressSpace(Kernel::VMManager& address_space) { | 162 | // TODO(yuriks): This flag seems to have some other effect, but it's unknown what |
| 119 | using namespace Kernel; | 163 | MemoryState memory_state = mapping.unk_flag ? MemoryState::Static : MemoryState::IO; |
| 120 | 164 | ||
| 121 | for (MemoryArea& area : memory_areas) { | 165 | auto vma = address_space |
| 122 | auto block = std::make_shared<std::vector<u8>>(area.size); | 166 | .MapBackingMemory(mapping.address, target_pointer + offset_into_region, |
| 123 | address_space | 167 | mapping.size, memory_state) |
| 124 | .MapMemoryBlock(area.base, std::move(block), 0, area.size, MemoryState::Private) | 168 | .MoveFrom(); |
| 125 | .Unwrap(); | 169 | address_space.Reprotect(vma, |
| 126 | } | 170 | mapping.read_only ? VMAPermission::Read : VMAPermission::ReadWrite); |
| 171 | } | ||
| 127 | 172 | ||
| 173 | void MapSharedPages(VMManager& address_space) { | ||
| 128 | auto cfg_mem_vma = address_space | 174 | auto cfg_mem_vma = address_space |
| 129 | .MapBackingMemory(CONFIG_MEMORY_VADDR, (u8*)&ConfigMem::config_mem, | 175 | .MapBackingMemory(Memory::CONFIG_MEMORY_VADDR, |
| 130 | CONFIG_MEMORY_SIZE, MemoryState::Shared) | 176 | reinterpret_cast<u8*>(&ConfigMem::config_mem), |
| 177 | Memory::CONFIG_MEMORY_SIZE, MemoryState::Shared) | ||
| 131 | .MoveFrom(); | 178 | .MoveFrom(); |
| 132 | address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); | 179 | address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); |
| 133 | 180 | ||
| 134 | auto shared_page_vma = address_space | 181 | auto shared_page_vma = address_space |
| 135 | .MapBackingMemory(SHARED_PAGE_VADDR, (u8*)&SharedPage::shared_page, | 182 | .MapBackingMemory(Memory::SHARED_PAGE_VADDR, |
| 136 | SHARED_PAGE_SIZE, MemoryState::Shared) | 183 | reinterpret_cast<u8*>(&SharedPage::shared_page), |
| 184 | Memory::SHARED_PAGE_SIZE, MemoryState::Shared) | ||
| 137 | .MoveFrom(); | 185 | .MoveFrom(); |
| 138 | address_space.Reprotect(shared_page_vma, VMAPermission::Read); | 186 | address_space.Reprotect(shared_page_vma, VMAPermission::Read); |
| 139 | |||
| 140 | AudioCore::AddAddressSpace(address_space); | ||
| 141 | } | 187 | } |
| 142 | 188 | ||
| 143 | } // namespace | 189 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index 4e1856a41..08c1a9989 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h | |||
| @@ -23,11 +23,7 @@ struct MemoryRegionInfo { | |||
| 23 | void MemoryInit(u32 mem_type); | 23 | void MemoryInit(u32 mem_type); |
| 24 | void MemoryShutdown(); | 24 | void MemoryShutdown(); |
| 25 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); | 25 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); |
| 26 | } | ||
| 27 | 26 | ||
| 28 | namespace Memory { | 27 | void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); |
| 29 | 28 | void MapSharedPages(VMManager& address_space); | |
| 30 | void Init(); | 29 | } // namespace Kernel |
| 31 | void InitLegacyAddressSpace(Kernel::VMManager& address_space); | ||
| 32 | |||
| 33 | } // namespace | ||
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index ba80fe7f8..32cb25fb7 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -35,7 +35,6 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) { | |||
| 35 | process->codeset = std::move(code_set); | 35 | process->codeset = std::move(code_set); |
| 36 | process->flags.raw = 0; | 36 | process->flags.raw = 0; |
| 37 | process->flags.memory_region.Assign(MemoryRegion::APPLICATION); | 37 | process->flags.memory_region.Assign(MemoryRegion::APPLICATION); |
| 38 | Memory::InitLegacyAddressSpace(process->vm_manager); | ||
| 39 | 38 | ||
| 40 | return process; | 39 | return process; |
| 41 | } | 40 | } |
| @@ -78,8 +77,15 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | |||
| 78 | 77 | ||
| 79 | AddressMapping mapping; | 78 | AddressMapping mapping; |
| 80 | mapping.address = descriptor << 12; | 79 | mapping.address = descriptor << 12; |
| 81 | mapping.size = (end_desc << 12) - mapping.address; | 80 | VAddr end_address = end_desc << 12; |
| 82 | mapping.writable = (descriptor & (1 << 20)) != 0; | 81 | |
| 82 | if (mapping.address < end_address) { | ||
| 83 | mapping.size = end_address - mapping.address; | ||
| 84 | } else { | ||
| 85 | mapping.size = 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | mapping.read_only = (descriptor & (1 << 20)) != 0; | ||
| 83 | mapping.unk_flag = (end_desc & (1 << 20)) != 0; | 89 | mapping.unk_flag = (end_desc & (1 << 20)) != 0; |
| 84 | 90 | ||
| 85 | address_mappings.push_back(mapping); | 91 | address_mappings.push_back(mapping); |
| @@ -88,8 +94,10 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | |||
| 88 | AddressMapping mapping; | 94 | AddressMapping mapping; |
| 89 | mapping.address = descriptor << 12; | 95 | mapping.address = descriptor << 12; |
| 90 | mapping.size = Memory::PAGE_SIZE; | 96 | mapping.size = Memory::PAGE_SIZE; |
| 91 | mapping.writable = true; // TODO: Not sure if correct | 97 | mapping.read_only = false; |
| 92 | mapping.unk_flag = false; | 98 | mapping.unk_flag = false; |
| 99 | |||
| 100 | address_mappings.push_back(mapping); | ||
| 93 | } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF | 101 | } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF |
| 94 | // Kernel version | 102 | // Kernel version |
| 95 | kernel_version = descriptor & 0xFFFF; | 103 | kernel_version = descriptor & 0xFFFF; |
| @@ -131,6 +139,12 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { | |||
| 131 | misc_memory_used += stack_size; | 139 | misc_memory_used += stack_size; |
| 132 | memory_region->used += stack_size; | 140 | memory_region->used += stack_size; |
| 133 | 141 | ||
| 142 | // Map special address mappings | ||
| 143 | MapSharedPages(vm_manager); | ||
| 144 | for (const auto& mapping : address_mappings) { | ||
| 145 | HandleSpecialMapping(vm_manager, mapping); | ||
| 146 | } | ||
| 147 | |||
| 134 | vm_manager.LogLayout(Log::Level::Debug); | 148 | vm_manager.LogLayout(Log::Level::Debug); |
| 135 | Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority); | 149 | Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority); |
| 136 | } | 150 | } |
| @@ -138,6 +152,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { | |||
| 138 | VAddr Process::GetLinearHeapAreaAddress() const { | 152 | VAddr Process::GetLinearHeapAreaAddress() const { |
| 139 | return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR; | 153 | return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR; |
| 140 | } | 154 | } |
| 155 | |||
| 141 | VAddr Process::GetLinearHeapBase() const { | 156 | VAddr Process::GetLinearHeapBase() const { |
| 142 | return GetLinearHeapAreaAddress() + memory_region->base; | 157 | return GetLinearHeapAreaAddress() + memory_region->base; |
| 143 | } | 158 | } |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index b566950b0..b52211d2a 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -20,7 +20,7 @@ struct AddressMapping { | |||
| 20 | // Address and size must be page-aligned | 20 | // Address and size must be page-aligned |
| 21 | VAddr address; | 21 | VAddr address; |
| 22 | u32 size; | 22 | u32 size; |
| 23 | bool writable; | 23 | bool read_only; |
| 24 | bool unk_flag; | 24 | bool unk_flag; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 65e4bba85..b8438e490 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -672,12 +672,14 @@ PAddr VirtualToPhysicalAddress(const VAddr addr) { | |||
| 672 | return addr - VRAM_VADDR + VRAM_PADDR; | 672 | return addr - VRAM_VADDR + VRAM_PADDR; |
| 673 | } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) { | 673 | } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) { |
| 674 | return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR; | 674 | return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR; |
| 675 | } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) { | ||
| 676 | return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR; | ||
| 675 | } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) { | 677 | } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) { |
| 676 | return addr - DSP_RAM_VADDR + DSP_RAM_PADDR; | 678 | return addr - DSP_RAM_VADDR + DSP_RAM_PADDR; |
| 677 | } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) { | 679 | } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) { |
| 678 | return addr - IO_AREA_VADDR + IO_AREA_PADDR; | 680 | return addr - IO_AREA_VADDR + IO_AREA_PADDR; |
| 679 | } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) { | 681 | } else if (addr >= N3DS_EXTRA_RAM_VADDR && addr < N3DS_EXTRA_RAM_VADDR_END) { |
| 680 | return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR; | 682 | return addr - N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_PADDR; |
| 681 | } | 683 | } |
| 682 | 684 | ||
| 683 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%08X", addr); | 685 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%08X", addr); |
| @@ -696,6 +698,8 @@ VAddr PhysicalToVirtualAddress(const PAddr addr) { | |||
| 696 | return addr - DSP_RAM_PADDR + DSP_RAM_VADDR; | 698 | return addr - DSP_RAM_PADDR + DSP_RAM_VADDR; |
| 697 | } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) { | 699 | } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) { |
| 698 | return addr - IO_AREA_PADDR + IO_AREA_VADDR; | 700 | return addr - IO_AREA_PADDR + IO_AREA_VADDR; |
| 701 | } else if (addr >= N3DS_EXTRA_RAM_PADDR && addr < N3DS_EXTRA_RAM_PADDR_END) { | ||
| 702 | return addr - N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_VADDR; | ||
| 699 | } | 703 | } |
| 700 | 704 | ||
| 701 | LOG_ERROR(HW_Memory, "Unknown physical address @ 0x%08X", addr); | 705 | LOG_ERROR(HW_Memory, "Unknown physical address @ 0x%08X", addr); |
diff --git a/src/core/memory.h b/src/core/memory.h index 903b58a22..802aa465e 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -37,6 +37,12 @@ enum : PAddr { | |||
| 37 | VRAM_SIZE = 0x00600000, ///< VRAM size (6MB) | 37 | VRAM_SIZE = 0x00600000, ///< VRAM size (6MB) |
| 38 | VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE, | 38 | VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE, |
| 39 | 39 | ||
| 40 | /// New 3DS additional memory. Supposedly faster than regular FCRAM. Part of it can be used by | ||
| 41 | /// applications and system modules if mapped via the ExHeader. | ||
| 42 | N3DS_EXTRA_RAM_PADDR = 0x1F000000, | ||
| 43 | N3DS_EXTRA_RAM_SIZE = 0x00400000, ///< New 3DS additional memory size (4MB) | ||
| 44 | N3DS_EXTRA_RAM_PADDR_END = N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_SIZE, | ||
| 45 | |||
| 40 | /// DSP memory | 46 | /// DSP memory |
| 41 | DSP_RAM_PADDR = 0x1FF00000, | 47 | DSP_RAM_PADDR = 0x1FF00000, |
| 42 | DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB) | 48 | DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB) |
| @@ -81,6 +87,10 @@ enum : VAddr { | |||
| 81 | LINEAR_HEAP_SIZE = 0x08000000, | 87 | LINEAR_HEAP_SIZE = 0x08000000, |
| 82 | LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE, | 88 | LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE, |
| 83 | 89 | ||
| 90 | /// Maps 1:1 to New 3DS additional memory | ||
| 91 | N3DS_EXTRA_RAM_VADDR = 0x1E800000, | ||
| 92 | N3DS_EXTRA_RAM_VADDR_END = N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_SIZE, | ||
| 93 | |||
| 84 | /// Maps 1:1 to the IO register area. | 94 | /// Maps 1:1 to the IO register area. |
| 85 | IO_AREA_VADDR = 0x1EC00000, | 95 | IO_AREA_VADDR = 0x1EC00000, |
| 86 | IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE, | 96 | IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE, |