From 81939e808f22276afc91aa1e770d1869b027eaf3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 11 Oct 2014 22:43:10 -0700 Subject: [PATCH 01/10] Memmap: Clean up indentation and whitespace a bit --- Source/Core/Core/HW/Memmap.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 049b53a0de..7fa8d6243d 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -119,19 +119,16 @@ bool IsInitialized() static const MemoryView views[] = { {&m_pRAM, &m_pPhysicalRAM, 0x00000000, RAM_SIZE, 0}, - {nullptr, &m_pVirtualCachedRAM, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, - {nullptr, &m_pVirtualUncachedRAM, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, - -// Don't map any memory for the EFB. We want all access to this area to go -// through the hardware access handlers. + {nullptr, &m_pVirtualCachedRAM, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, + {nullptr, &m_pVirtualUncachedRAM, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, {&m_pL1Cache, &m_pVirtualL1Cache, 0xE0000000, L1_CACHE_SIZE, 0}, {&m_pFakeVMEM, &m_pVirtualFakeVMEM, 0x7E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM}, {&m_pEXRAM, &m_pPhysicalEXRAM, 0x10000000, EXRAM_SIZE, MV_WII_ONLY}, - {nullptr, &m_pVirtualCachedEXRAM, 0x90000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, - {nullptr, &m_pVirtualUncachedEXRAM, 0xD0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, + {nullptr, &m_pVirtualCachedEXRAM, 0x90000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, + {nullptr, &m_pVirtualUncachedEXRAM, 0xD0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, }; static const int num_views = sizeof(views) / sizeof(MemoryView); From 48aff73b6ad60ebfa19df183f63ec8c58624d68d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 02:47:53 -0700 Subject: [PATCH 02/10] MemArena: Remove duplicated code I can't find any obvious difference between these two paths. --- Source/Core/Common/MemArena.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Source/Core/Common/MemArena.cpp b/Source/Core/Common/MemArena.cpp index 16eecf33d6..88cf92a70c 100644 --- a/Source/Core/Common/MemArena.cpp +++ b/Source/Core/Common/MemArena.cpp @@ -244,7 +244,6 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena arena->GrabLowMemSpace(total_mem); // Now, create views in high memory where there's plenty of space. -#if _ARCH_64 u8 *base = MemArena::Find4GBBase(); // This really shouldn't fail - in 64-bit, there will always be enough // address space. @@ -254,16 +253,6 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena exit(0); return nullptr; } -#else - // Linux32 is fine with the x64 method, although limited to 32-bit with no automirrors. - u8 *base = MemArena::Find4GBBase(); - if (!Memory_TryBase(base, views, num_views, flags, arena)) - { - PanicAlert("MemoryMap_Setup: Failed finding a memory base."); - exit(0); - return 0; - } -#endif return base; } From 6317721c9581f83cd43219f022d8ef3ed7e6dfa3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 03:06:05 -0700 Subject: [PATCH 03/10] MemmapFunctions: Remove unused effective_address argument --- Source/Core/Core/HW/MemmapFunctions.cpp | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/HW/MemmapFunctions.cpp b/Source/Core/Core/HW/MemmapFunctions.cpp index 194555004c..26ea59e4eb 100644 --- a/Source/Core/Core/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/HW/MemmapFunctions.cpp @@ -90,7 +90,7 @@ static u32 EFB_Read(const u32 addr) static void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite); template -inline void ReadFromHardware(T &_var, const u32 em_address, const u32 effective_address, Memory::XCheckTLBFlag flag) +inline void ReadFromHardware(T &_var, const u32 em_address, Memory::XCheckTLBFlag flag) { // TODO: Figure out the fastest order of tests for both read and write (they are probably different). if ((em_address & 0xC8000000) == 0xC8000000) @@ -197,7 +197,7 @@ inline void ReadFromHardware(T &_var, const u32 em_address, const u32 effective_ template -inline void WriteToHardware(u32 em_address, const T data, u32 effective_address, Memory::XCheckTLBFlag flag) +inline void WriteToHardware(u32 em_address, const T data, Memory::XCheckTLBFlag flag) { // First, let's check for FIFO writes, since they are probably the most common // reason we end up in this function: @@ -368,7 +368,7 @@ u32 Read_Opcode(u32 _Address) u8 Read_U8(const u32 _Address) { u8 _var = 0; - ReadFromHardware(_var, _Address, _Address, FLAG_READ); + ReadFromHardware(_var, _Address, FLAG_READ); #ifdef ENABLE_MEM_CHECK TMemCheck *mc = PowerPC::memchecks.GetMemCheck(_Address); if (mc) @@ -383,7 +383,7 @@ u8 Read_U8(const u32 _Address) u16 Read_U16(const u32 _Address) { u16 _var = 0; - ReadFromHardware(_var, _Address, _Address, FLAG_READ); + ReadFromHardware(_var, _Address, FLAG_READ); #ifdef ENABLE_MEM_CHECK TMemCheck *mc = PowerPC::memchecks.GetMemCheck(_Address); if (mc) @@ -398,7 +398,7 @@ u16 Read_U16(const u32 _Address) u32 Read_U32(const u32 _Address) { u32 _var = 0; - ReadFromHardware(_var, _Address, _Address, FLAG_READ); + ReadFromHardware(_var, _Address, FLAG_READ); #ifdef ENABLE_MEM_CHECK TMemCheck *mc = PowerPC::memchecks.GetMemCheck(_Address); if (mc) @@ -413,7 +413,7 @@ u32 Read_U32(const u32 _Address) u64 Read_U64(const u32 _Address) { u64 _var = 0; - ReadFromHardware(_var, _Address, _Address, FLAG_READ); + ReadFromHardware(_var, _Address, FLAG_READ); #ifdef ENABLE_MEM_CHECK TMemCheck *mc = PowerPC::memchecks.GetMemCheck(_Address); if (mc) @@ -469,7 +469,7 @@ void Write_U8(const u8 _Data, const u32 _Address) mc->Action(&PowerPC::debug_interface, _Data,_Address,true,1,PC); } #endif - WriteToHardware(_Address, _Data, _Address, FLAG_WRITE); + WriteToHardware(_Address, _Data, FLAG_WRITE); } @@ -484,7 +484,7 @@ void Write_U16(const u16 _Data, const u32 _Address) } #endif - WriteToHardware(_Address, _Data, _Address, FLAG_WRITE); + WriteToHardware(_Address, _Data, FLAG_WRITE); } void Write_U16_Swap(const u16 _Data, const u32 _Address) { @@ -502,7 +502,7 @@ void Write_U32(const u32 _Data, const u32 _Address) mc->Action(&PowerPC::debug_interface, _Data,_Address,true,4,PC); } #endif - WriteToHardware(_Address, _Data, _Address, FLAG_WRITE); + WriteToHardware(_Address, _Data, FLAG_WRITE); } void Write_U32_Swap(const u32 _Data, const u32 _Address) { @@ -520,7 +520,7 @@ void Write_U64(const u64 _Data, const u32 _Address) } #endif - WriteToHardware(_Address, _Data, _Address + 4, FLAG_WRITE); + WriteToHardware(_Address, _Data, FLAG_WRITE); } void Write_U64_Swap(const u64 _Data, const u32 _Address) { @@ -540,7 +540,7 @@ void Write_F64(const double _Data, const u32 _Address) u8 ReadUnchecked_U8(const u32 _Address) { u8 _var = 0; - ReadFromHardware(_var, _Address, _Address, FLAG_NO_EXCEPTION); + ReadFromHardware(_var, _Address, FLAG_NO_EXCEPTION); return _var; } @@ -548,19 +548,19 @@ u8 ReadUnchecked_U8(const u32 _Address) u32 ReadUnchecked_U32(const u32 _Address) { u32 _var = 0; - ReadFromHardware(_var, _Address, _Address, FLAG_NO_EXCEPTION); + ReadFromHardware(_var, _Address, FLAG_NO_EXCEPTION); return _var; } void WriteUnchecked_U8(const u8 _iValue, const u32 _Address) { - WriteToHardware(_Address, _iValue, _Address, FLAG_NO_EXCEPTION); + WriteToHardware(_Address, _iValue, FLAG_NO_EXCEPTION); } void WriteUnchecked_U32(const u32 _iValue, const u32 _Address) { - WriteToHardware(_Address, _iValue, _Address, FLAG_NO_EXCEPTION); + WriteToHardware(_Address, _iValue, FLAG_NO_EXCEPTION); } // ********************************************************************************* From 5a2340fead89f630e3966c4c6f430a1c3f44ddaf Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 03:17:12 -0700 Subject: [PATCH 04/10] Memmap: Make the constants aligned to 8 nibble characters Otherwise, the constants can be a bit confusing to read. --- Source/Core/Core/HW/Memmap.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index e10eec6cbf..57be35c554 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -48,11 +48,11 @@ enum RAM_MASK = RAM_SIZE - 1, FAKEVMEM_SIZE = 0x02000000, FAKEVMEM_MASK = FAKEVMEM_SIZE - 1, - L1_CACHE_SIZE = 0x40000, + L1_CACHE_SIZE = 0x00040000, L1_CACHE_MASK = L1_CACHE_SIZE - 1, - EFB_SIZE = 0x200000, + EFB_SIZE = 0x00200000, EFB_MASK = EFB_SIZE - 1, - IO_SIZE = 0x10000, + IO_SIZE = 0x00010000, EXRAM_SIZE = 0x04000000, EXRAM_MASK = EXRAM_SIZE - 1, From 4a59750b305d5df092068ca3df0b6d32c1f4aa1d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 03:45:01 -0700 Subject: [PATCH 05/10] MemArena: Bail on Arch64 if the out_ptr allocation fails --- Source/Core/Common/MemArena.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Core/Common/MemArena.cpp b/Source/Core/Common/MemArena.cpp index 88cf92a70c..5c3972d44a 100644 --- a/Source/Core/Common/MemArena.cpp +++ b/Source/Core/Common/MemArena.cpp @@ -214,10 +214,11 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 { *views[i].out_ptr = (u8*)arena->CreateView( position, views[i].size, base + (views[i].virtual_address & 0x3FFFFFFF)); - if (!*views[i].out_ptr) - goto bail; } #endif + if (!*views[i].out_ptr) + goto bail; + last_position = position; position += views[i].size; } From dd0aadac9751f93fadbe4d2d3446eb621369a7c5 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 03:57:28 -0700 Subject: [PATCH 06/10] MemoryWindow: Use p_pFakeVMEM, not the virtual mirror They point to the same contents, so there's no reason to use the mirror. This lets us make all the mirrors static. --- Source/Core/Core/HW/Memmap.cpp | 2 +- Source/Core/Core/HW/Memmap.h | 1 - Source/Core/DolphinWX/Debugger/MemoryWindow.cpp | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 7fa8d6243d..2483ac4906 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -79,7 +79,7 @@ static u8* m_pPhysicalEXRAM; // wii only static u8* m_pVirtualCachedEXRAM; // wii only static u8* m_pVirtualUncachedEXRAM; // wii only static u8* m_pVirtualL1Cache; -u8* m_pVirtualFakeVMEM; +static u8* m_pVirtualFakeVMEM; // MMIO mapping object. MMIO::Mapping* mmio_mapping; diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index 57be35c554..bc312646f8 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -33,7 +33,6 @@ extern u8* base; extern u8* m_pRAM; extern u8* m_pEXRAM; extern u8* m_pL1Cache; -extern u8* m_pVirtualFakeVMEM; extern u8* m_pFakeVMEM; extern bool bFakeVMEM; diff --git a/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp b/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp index 60978b6693..c620d327c6 100644 --- a/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp +++ b/Source/Core/DolphinWX/Debugger/MemoryWindow.cpp @@ -278,7 +278,7 @@ void CMemoryWindow::OnDumpMem2( wxCommandEvent& event ) // Write fake vmem to file void CMemoryWindow::OnDumpFakeVMEM( wxCommandEvent& event ) { - DumpArray(File::GetUserPath(F_FAKEVMEMDUMP_IDX), Memory::m_pVirtualFakeVMEM, Memory::FAKEVMEM_SIZE); + DumpArray(File::GetUserPath(F_FAKEVMEMDUMP_IDX), Memory::m_pFakeVMEM, Memory::FAKEVMEM_SIZE); } void CMemoryWindow::U8(wxCommandEvent& event) From 8858dc776467af45b95cf40ea7db7aebfc0e157d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 03:58:39 -0700 Subject: [PATCH 07/10] Memmap: Remove vestigals of the memory-mapped EFB It hasn't been memory-mapped for a long time. --- Source/Core/Core/HW/Memmap.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index bc312646f8..8c6a00c128 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -49,8 +49,6 @@ enum FAKEVMEM_MASK = FAKEVMEM_SIZE - 1, L1_CACHE_SIZE = 0x00040000, L1_CACHE_MASK = L1_CACHE_SIZE - 1, - EFB_SIZE = 0x00200000, - EFB_MASK = EFB_SIZE - 1, IO_SIZE = 0x00010000, EXRAM_SIZE = 0x04000000, EXRAM_MASK = EXRAM_SIZE - 1, From 6813473367dbbeee67375311a8991cedfc72eaea Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 04:02:12 -0700 Subject: [PATCH 08/10] MemArena: Remove the low mappings for our pointers These are effectively unused, since the memmap already maps them in one place. For 32-bit, they might have some slight advantage, but we already special-case the regular "high-mem" pointer for 32-bit, so just use the one we already have... --- Source/Core/Common/MemArena.cpp | 48 ++++++++++++------------------- Source/Core/Common/MemArena.h | 8 +++--- Source/Core/Core/HW/Memmap.cpp | 51 +++++++++++---------------------- 3 files changed, 39 insertions(+), 68 deletions(-) diff --git a/Source/Core/Common/MemArena.cpp b/Source/Core/Common/MemArena.cpp index 5c3972d44a..237dc4356f 100644 --- a/Source/Core/Common/MemArena.cpp +++ b/Source/Core/Common/MemArena.cpp @@ -170,8 +170,7 @@ u8* MemArena::Find4GBBase() if (!(a_flags & MV_FAKE_VMEM) && (b_flags & MV_FAKE_VMEM)) \ continue; \ - -static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 flags, MemArena *arena) +static bool Memory_TryBase(u8 *base, MemoryView *views, int num_views, u32 flags, MemArena *arena) { // OK, we know where to find free space. Now grab it! // We just mimic the popular BAT setup. @@ -181,45 +180,38 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 // Zero all the pointers to be sure. for (int i = 0; i < num_views; i++) { - if (views[i].out_ptr_low) - *views[i].out_ptr_low = nullptr; - if (views[i].out_ptr) - *views[i].out_ptr = nullptr; + views[i].mapped_ptr = nullptr; } int i; for (i = 0; i < num_views; i++) { SKIP(flags, views[i].flags); + if (views[i].flags & MV_MIRROR_PREVIOUS) - { position = last_position; - } - else - { - *(views[i].out_ptr_low) = (u8*)arena->CreateView(position, views[i].size); - if (!*views[i].out_ptr_low) - goto bail; - } + #if _ARCH_64 - *views[i].out_ptr = (u8*)arena->CreateView( + views[i].mapped_ptr = arena->CreateView( position, views[i].size, base + views[i].virtual_address); #else if (views[i].flags & MV_MIRROR_PREVIOUS) { // No need to create multiple identical views. - *views[i].out_ptr = *views[i - 1].out_ptr; + views[i].mapped_ptr = views[i - 1].mapped_ptr; } else { - *views[i].out_ptr = (u8*)arena->CreateView( + views[i].mapped_ptr = arena->CreateView( position, views[i].size, base + (views[i].virtual_address & 0x3FFFFFFF)); } #endif - if (!*views[i].out_ptr) + if (!views[i].mapped_ptr) goto bail; - last_position = position; + if (views[i].out_ptr) + *views[i].out_ptr = (u8*) views[i].mapped_ptr; + position += views[i].size; } @@ -231,7 +223,7 @@ bail: return false; } -u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena *arena) +u8 *MemoryMap_Setup(MemoryView *views, int num_views, u32 flags, MemArena *arena) { u32 total_mem = 0; @@ -258,21 +250,17 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena return base; } -void MemoryMap_Shutdown(const MemoryView *views, int num_views, u32 flags, MemArena *arena) +void MemoryMap_Shutdown(MemoryView *views, int num_views, u32 flags, MemArena *arena) { std::set freeset; for (int i = 0; i < num_views; i++) { - const MemoryView* view = &views[i]; - u8** outptrs[2] = {view->out_ptr_low, view->out_ptr}; - for (auto outptr : outptrs) + MemoryView* view = &views[i]; + if (view->mapped_ptr && *(u8*)view->mapped_ptr && !freeset.count(view->mapped_ptr)) { - if (outptr && *outptr && !freeset.count(*outptr)) - { - arena->ReleaseView(*outptr, view->size); - freeset.insert(*outptr); - *outptr = nullptr; - } + arena->ReleaseView(view->mapped_ptr, view->size); + freeset.insert(view->mapped_ptr); + view->mapped_ptr = nullptr; } } } diff --git a/Source/Core/Common/MemArena.h b/Source/Core/Common/MemArena.h index ccfc962f22..2cc6dc3f27 100644 --- a/Source/Core/Common/MemArena.h +++ b/Source/Core/Common/MemArena.h @@ -43,14 +43,14 @@ enum { struct MemoryView { - u8 **out_ptr_low; - u8 **out_ptr; + u8** out_ptr; u32 virtual_address; u32 size; u32 flags; + void* mapped_ptr; }; // Uses a memory arena to set up an emulator-friendly memory map according to // a passed-in list of MemoryView structures. -u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena *arena); -void MemoryMap_Shutdown(const MemoryView *views, int num_views, u32 flags, MemArena *arena); +u8 *MemoryMap_Setup(MemoryView *views, int num_views, u32 flags, MemArena *arena); +void MemoryMap_Shutdown(MemoryView *views, int num_views, u32 flags, MemArena *arena); diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 2483ac4906..21387577bd 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -63,24 +63,11 @@ static MemArena g_arena; static bool m_IsInitialized = false; // Save the Init(), Shutdown() state // END STATE_TO_SAVE -// 64-bit: Pointers to low-mem (sub-0x10000000) mirror -// 32-bit: Same as the corresponding physical/virtual pointers. u8* m_pRAM; u8* m_pL1Cache; u8* m_pEXRAM; u8* m_pFakeVMEM; -// 64-bit: Pointers to high-mem mirrors -// 32-bit: Same as above -static u8* m_pPhysicalRAM; -static u8* m_pVirtualCachedRAM; -static u8* m_pVirtualUncachedRAM; -static u8* m_pPhysicalEXRAM; // wii only -static u8* m_pVirtualCachedEXRAM; // wii only -static u8* m_pVirtualUncachedEXRAM; // wii only -static u8* m_pVirtualL1Cache; -static u8* m_pVirtualFakeVMEM; - // MMIO mapping object. MMIO::Mapping* mmio_mapping; @@ -116,19 +103,16 @@ bool IsInitialized() // We don't declare the IO region in here since its handled by other means. -static const MemoryView views[] = +static MemoryView views[] = { - {&m_pRAM, &m_pPhysicalRAM, 0x00000000, RAM_SIZE, 0}, - {nullptr, &m_pVirtualCachedRAM, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, - {nullptr, &m_pVirtualUncachedRAM, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, - - {&m_pL1Cache, &m_pVirtualL1Cache, 0xE0000000, L1_CACHE_SIZE, 0}, - - {&m_pFakeVMEM, &m_pVirtualFakeVMEM, 0x7E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM}, - - {&m_pEXRAM, &m_pPhysicalEXRAM, 0x10000000, EXRAM_SIZE, MV_WII_ONLY}, - {nullptr, &m_pVirtualCachedEXRAM, 0x90000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, - {nullptr, &m_pVirtualUncachedEXRAM, 0xD0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, + {&m_pRAM, 0x00000000, RAM_SIZE, 0}, + {nullptr, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, + {nullptr, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, + {&m_pL1Cache, 0xE0000000, L1_CACHE_SIZE, 0}, + {&m_pFakeVMEM, 0x7E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM}, + {&m_pEXRAM, 0x10000000, EXRAM_SIZE, MV_WII_ONLY}, + {nullptr, 0x90000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, + {nullptr, 0xD0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS}, }; static const int num_views = sizeof(views) / sizeof(MemoryView); @@ -154,19 +138,18 @@ void Init() else InitMMIO(mmio_mapping); - INFO_LOG(MEMMAP, "Memory system initialized. RAM at %p (mirrors at 0 @ %p, 0x80000000 @ %p , 0xC0000000 @ %p)", - m_pRAM, m_pPhysicalRAM, m_pVirtualCachedRAM, m_pVirtualUncachedRAM); + INFO_LOG(MEMMAP, "Memory system initialized. RAM at %p", m_pRAM); m_IsInitialized = true; } void DoState(PointerWrap &p) { bool wii = SConfig::GetInstance().m_LocalCoreStartupParameter.bWii; - p.DoArray(m_pPhysicalRAM, RAM_SIZE); - p.DoArray(m_pVirtualL1Cache, L1_CACHE_SIZE); + p.DoArray(m_pRAM, RAM_SIZE); + p.DoArray(m_pL1Cache, L1_CACHE_SIZE); p.DoMarker("Memory RAM"); if (bFakeVMEM) - p.DoArray(m_pVirtualFakeVMEM, FAKEVMEM_SIZE); + p.DoArray(m_pFakeVMEM, FAKEVMEM_SIZE); p.DoMarker("Memory FakeVMEM"); if (wii) p.DoArray(m_pEXRAM, EXRAM_SIZE); @@ -328,7 +311,7 @@ u8* GetPointer(const u32 _Address) case 0x0: case 0x8: if ((_Address & 0xfffffff) < REALRAM_SIZE) - return m_pPhysicalRAM + (_Address & RAM_MASK); + return m_pRAM + (_Address & RAM_MASK); case 0xc: switch (_Address >> 24) { @@ -341,7 +324,7 @@ u8* GetPointer(const u32 _Address) default: if ((_Address & 0xfffffff) < REALRAM_SIZE) - return m_pPhysicalRAM + (_Address & RAM_MASK); + return m_pRAM + (_Address & RAM_MASK); } case 0x1: @@ -350,7 +333,7 @@ u8* GetPointer(const u32 _Address) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) { if ((_Address & 0xfffffff) < EXRAM_SIZE) - return m_pPhysicalEXRAM + (_Address & EXRAM_MASK); + return m_pEXRAM + (_Address & EXRAM_MASK); } else break; @@ -363,7 +346,7 @@ u8* GetPointer(const u32 _Address) default: if (bFakeVMEM) - return m_pVirtualFakeVMEM + (_Address & FAKEVMEM_MASK); + return m_pFakeVMEM + (_Address & FAKEVMEM_MASK); } ERROR_LOG(MEMMAP, "Unknown Pointer %#8x PC %#8x LR %#8x", _Address, PC, LR); From 079b881d207face8912d0ad7b2ad6bac51ea8d40 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 28 Oct 2014 04:44:59 -0700 Subject: [PATCH 09/10] MemArena: Clean up the code that does the mirroring --- Source/Core/Common/MemArena.cpp | 47 ++++++++++++++++++++------------- Source/Core/Common/MemArena.h | 2 ++ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Source/Core/Common/MemArena.cpp b/Source/Core/Common/MemArena.cpp index 237dc4356f..5a5394ade4 100644 --- a/Source/Core/Common/MemArena.cpp +++ b/Source/Core/Common/MemArena.cpp @@ -174,45 +174,56 @@ static bool Memory_TryBase(u8 *base, MemoryView *views, int num_views, u32 flags { // OK, we know where to find free space. Now grab it! // We just mimic the popular BAT setup. - u32 position = 0; - u32 last_position = 0; + u32 shm_position = 0; // Zero all the pointers to be sure. for (int i = 0; i < num_views; i++) { views[i].mapped_ptr = nullptr; + + if (!(views[i].flags & MV_MIRROR_PREVIOUS) && i > 0) + shm_position += views[i - 1].size; + + views[i].shm_position = shm_position; } int i; for (i = 0; i < num_views; i++) { - SKIP(flags, views[i].flags); + MemoryView* view = &views[i]; + void* view_base; + bool use_sw_mirror; - if (views[i].flags & MV_MIRROR_PREVIOUS) - position = last_position; + SKIP(flags, view->flags); #if _ARCH_64 - views[i].mapped_ptr = arena->CreateView( - position, views[i].size, base + views[i].virtual_address); + // On 64-bit, we map the same file position multiple times, so we + // don't need the software fallback for the mirrors. + view_base = base + view->virtual_address; + use_sw_mirror = false; #else - if (views[i].flags & MV_MIRROR_PREVIOUS) + // On 32-bit, we don't have the actual address space to store all + // the mirrors, so we just map the fallbacks somewhere in our address + // space and use the software fallbacks for mirroring. + view_base = base + (view->virtual_address & 0x3FFFFFFF); + use_sw_mirror = true; +#endif + + if (use_sw_mirror && (view->flags & MV_MIRROR_PREVIOUS)) { - // No need to create multiple identical views. - views[i].mapped_ptr = views[i - 1].mapped_ptr; + view->view_ptr = views[i - 1].view_ptr; } else { - views[i].mapped_ptr = arena->CreateView( - position, views[i].size, base + (views[i].virtual_address & 0x3FFFFFFF)); + view->mapped_ptr = arena->CreateView(view->shm_position, view->size, view_base); + view->view_ptr = view->mapped_ptr; } -#endif - if (!views[i].mapped_ptr) + + if (!view->view_ptr) goto bail; - if (views[i].out_ptr) - *views[i].out_ptr = (u8*) views[i].mapped_ptr; - - position += views[i].size; + if (view->out_ptr) + *(view->out_ptr) = (u8*) view->view_ptr; } return true; diff --git a/Source/Core/Common/MemArena.h b/Source/Core/Common/MemArena.h index 2cc6dc3f27..d3ca8209c3 100644 --- a/Source/Core/Common/MemArena.h +++ b/Source/Core/Common/MemArena.h @@ -48,6 +48,8 @@ struct MemoryView u32 size; u32 flags; void* mapped_ptr; + void* view_ptr; + u32 shm_position; }; // Uses a memory arena to set up an emulator-friendly memory map according to From 1e93b0db19c06680f4bb0002d99920c1c987ae88 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Nov 2014 13:30:14 -0700 Subject: [PATCH 10/10] MemArena: Rename GrabLowMemSpace to GrabSHMSegment This code originally tried to map the "low space" for the Gamecube's memory layout, but since has expanded to mapping all of the easily mappable memory on the system. Change the name to "GrabSHMSegment" to indicate that we're looking for a shared memory segment we can map into our process space. --- Source/Core/Common/MemArena.cpp | 8 ++++---- Source/Core/Common/MemArena.h | 4 ++-- Source/Core/Core/HW/Memmap.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Core/Common/MemArena.cpp b/Source/Core/Common/MemArena.cpp index 5a5394ade4..60ad058778 100644 --- a/Source/Core/Common/MemArena.cpp +++ b/Source/Core/Common/MemArena.cpp @@ -49,7 +49,7 @@ static int AshmemCreateFileMapping(const char *name, size_t size) } #endif -void MemArena::GrabLowMemSpace(size_t size) +void MemArena::GrabSHMSegment(size_t size) { #ifdef _WIN32 hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, (DWORD)(size), nullptr); @@ -82,7 +82,7 @@ void MemArena::GrabLowMemSpace(size_t size) } -void MemArena::ReleaseSpace() +void MemArena::ReleaseSHMSegment() { #ifdef _WIN32 CloseHandle(hMemoryMapping); @@ -244,8 +244,8 @@ u8 *MemoryMap_Setup(MemoryView *views, int num_views, u32 flags, MemArena *arena if ((views[i].flags & MV_MIRROR_PREVIOUS) == 0) total_mem += views[i].size; } - // Grab some pagefile backed memory out of the void ... - arena->GrabLowMemSpace(total_mem); + + arena->GrabSHMSegment(total_mem); // Now, create views in high memory where there's plenty of space. u8 *base = MemArena::Find4GBBase(); diff --git a/Source/Core/Common/MemArena.h b/Source/Core/Common/MemArena.h index d3ca8209c3..67482432fd 100644 --- a/Source/Core/Common/MemArena.h +++ b/Source/Core/Common/MemArena.h @@ -19,8 +19,8 @@ class MemArena { public: - void GrabLowMemSpace(size_t size); - void ReleaseSpace(); + void GrabSHMSegment(size_t size); + void ReleaseSHMSegment(); void *CreateView(s64 offset, size_t size, void *base = nullptr); void ReleaseView(void *view, size_t size); diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 21387577bd..d89647592e 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -163,7 +163,7 @@ void Shutdown() if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) flags |= MV_WII_ONLY; if (bFakeVMEM) flags |= MV_FAKE_VMEM; MemoryMap_Shutdown(views, num_views, flags, &g_arena); - g_arena.ReleaseSpace(); + g_arena.ReleaseSHMSegment(); base = nullptr; delete mmio_mapping; INFO_LOG(MEMMAP, "Memory system shut down.");