diff --git a/Common/MemArena.cpp b/Common/MemArena.cpp index 987adc3a1f..f228c6274a 100644 --- a/Common/MemArena.cpp +++ b/Common/MemArena.cpp @@ -268,6 +268,8 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 for (i = 0; i < num_views; i++) { const MemoryView &view = views[i]; + if (view.size == 0) + continue; SKIP(flags, view.flags); if (view.flags & MV_MIRROR_PREVIOUS) { position = last_position; @@ -308,6 +310,8 @@ bail: // Argh! ERROR! Free what we grabbed so far so we can try again. for (int j = 0; j <= i; j++) { + if (views[i].size == 0) + continue; SKIP(flags, views[i].flags); if (views[j].out_ptr_low && *views[j].out_ptr_low) { @@ -337,6 +341,8 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena for (int i = 0; i < num_views; i++) { + if (views[i].size == 0) + continue; SKIP(flags, views[i].flags); if ((views[i].flags & MV_MIRROR_PREVIOUS) == 0) total_mem += roundup(views[i].size); @@ -403,6 +409,8 @@ void MemoryMap_Shutdown(const MemoryView *views, int num_views, u32 flags, MemAr { for (int i = 0; i < num_views; i++) { + if (views[i].size == 0) + continue; SKIP(flags, views[i].flags); if (views[i].out_ptr_low && *views[i].out_ptr_low) arena->ReleaseView(*views[i].out_ptr_low, views[i].size); diff --git a/Common/MemArena.h b/Common/MemArena.h index 79165ad8b4..20093770b7 100644 --- a/Common/MemArena.h +++ b/Common/MemArena.h @@ -60,6 +60,8 @@ enum { // MV_FAKE_VMEM = 2, // MV_WII_ONLY = 4, MV_IS_PRIMARY_RAM = 0x100, + MV_IS_EXTRA1_RAM = 0x200, + MV_IS_EXTRA2_RAM = 0x400, }; struct MemoryView diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 6f90c434ce..69ee0c5c5e 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -42,6 +42,8 @@ MemArena g_arena; // 64-bit: Pointers to low-mem (sub-0x10000000) mirror // 32-bit: Same as the corresponding physical/virtual pointers. u8 *m_pRAM; +u8 *m_pRAM2; +u8 *m_pRAM3; u8 *m_pScratchPad; u8 *m_pVRAM; @@ -52,6 +54,12 @@ u8 *m_pUncachedScratchPad; u8 *m_pPhysicalRAM; u8 *m_pUncachedRAM; u8 *m_pKernelRAM; // RAM mirrored up to "kernel space". Fully accessible at all times currently. +u8 *m_pPhysicalRAM2; +u8 *m_pUncachedRAM2; +u8 *m_pKernelRAM2; +u8 *m_pPhysicalRAM3; +u8 *m_pUncachedRAM3; +u8 *m_pKernelRAM3; u8 *m_pPhysicalVRAM; u8 *m_pUncachedVRAM; @@ -74,6 +82,14 @@ static MemoryView views[] = {&m_pRAM, &m_pPhysicalRAM, 0x08000000, g_MemorySize, MV_IS_PRIMARY_RAM}, // only from 0x08800000 is it usable (last 24 megs) {NULL, &m_pUncachedRAM, 0x48000000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_PRIMARY_RAM}, {NULL, &m_pKernelRAM, 0x88000000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_PRIMARY_RAM}, + // Starts at memory + 31 MB. + {&m_pRAM2, &m_pPhysicalRAM2, 0x09F00000, g_MemorySize, MV_IS_EXTRA1_RAM}, + {NULL, &m_pUncachedRAM2, 0x49F00000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_EXTRA1_RAM}, + {NULL, &m_pKernelRAM2, 0x89F00000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_EXTRA1_RAM}, + // Starts at memory + 31 * 2 MB. + {&m_pRAM3, &m_pPhysicalRAM3, 0x0BE00000, g_MemorySize, MV_IS_EXTRA2_RAM}, + {NULL, &m_pUncachedRAM3, 0x4BE00000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_EXTRA2_RAM}, + {NULL, &m_pKernelRAM3, 0x8BE00000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_EXTRA2_RAM}, // TODO: There are a few swizzled mirrors of VRAM, not sure about the best way to // implement those. @@ -89,9 +105,16 @@ void Init() // Using (Memory::g_MemorySize - 1) won't work for e.g. 0x04C00000. Memory::g_MemoryMask = 0x07FFFFFF; + // On some 32 bit platforms, you can only map < 32 megs at a time. + const static int MAX_MMAP_SIZE = 31 * 1024 * 1024; + _dbg_assert_msg_(MEMAP, g_MemorySize < MAX_MMAP_SIZE * 3, "ACK - too much memory for three mmap views."); for (size_t i = 0; i < ARRAY_SIZE(views); i++) { if (views[i].flags & MV_IS_PRIMARY_RAM) - views[i].size = g_MemorySize; + views[i].size = std::min((int)g_MemorySize, MAX_MMAP_SIZE); + if (views[i].flags & MV_IS_EXTRA1_RAM) + views[i].size = std::min(std::max((int)g_MemorySize - MAX_MMAP_SIZE, 0), MAX_MMAP_SIZE); + if (views[i].flags & MV_IS_EXTRA2_RAM) + views[i].size = std::min(std::max((int)g_MemorySize - MAX_MMAP_SIZE * 2, 0), MAX_MMAP_SIZE); } base = MemoryMap_Setup(views, num_views, flags, &g_arena); @@ -116,7 +139,7 @@ void DoState(PointerWrap &p) g_MemorySize = g_PSPModel == PSP_MODEL_FAT ? RAM_NORMAL_SIZE : RAM_DOUBLE_SIZE; } - p.DoArray(m_pRAM, g_MemorySize); + p.DoArray(GetPointer(PSP_GetKernelMemoryBase()), g_MemorySize); p.DoMarker("RAM"); p.DoArray(m_pVRAM, VRAM_SIZE); @@ -137,7 +160,7 @@ void Shutdown() void Clear() { if (m_pRAM) - memset(m_pRAM, 0, g_MemorySize); + memset(GetPointerUnchecked(PSP_GetKernelMemoryBase()), 0, g_MemorySize); if (m_pScratchPad) memset(m_pScratchPad, 0, SCRATCHPAD_SIZE); if (m_pVRAM) diff --git a/Core/MemMap.h b/Core/MemMap.h index 7f0ec6d814..9ae6488315 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -60,7 +60,10 @@ extern u8 *base; // These are guaranteed to point to "low memory" addresses (sub-32-bit). // 64-bit: Pointers to low-mem (sub-0x10000000) mirror // 32-bit: Same as the corresponding physical/virtual pointers. +// Broken into three chunks to workaround 32-bit mmap() limits. extern u8 *m_pRAM; +extern u8 *m_pRAM2; +extern u8 *m_pRAM3; extern u8 *m_pScratchPad; extern u8 *m_pVRAM; diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index 3938b918cf..c8fa0b6a4a 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -40,7 +40,7 @@ namespace Memory u8 *GetPointer(const u32 address) { if ((address & 0x3E000000) == 0x08000000) { - return m_pRAM + (address & RAM_NORMAL_MASK); + return GetPointerUnchecked(address); } else if ((address & 0x3F800000) == 0x04000000) { return m_pVRAM + (address & VRAM_MASK); @@ -49,7 +49,7 @@ u8 *GetPointer(const u32 address) return m_pScratchPad + (address & SCRATCHPAD_MASK); } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { - return m_pRAM + (address & g_MemoryMask); + return GetPointerUnchecked(address); } else { ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); @@ -75,7 +75,7 @@ inline void ReadFromHardware(T &var, const u32 address) // Could just do a base-relative read, too.... TODO if ((address & 0x3E000000) == 0x08000000) { - var = *((const T*)&m_pRAM[address & RAM_NORMAL_MASK]); + var = *((const T*)GetPointerUnchecked(address)); } else if ((address & 0x3F800000) == 0x04000000) { var = *((const T*)&m_pVRAM[address & VRAM_MASK]); @@ -85,7 +85,7 @@ inline void ReadFromHardware(T &var, const u32 address) var = *((const T*)&m_pScratchPad[address & SCRATCHPAD_MASK]); } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { - var = *((const T*)&m_pRAM[address & g_MemoryMask]); + var = *((const T*)GetPointerUnchecked(address)); } else { @@ -113,7 +113,7 @@ inline void WriteToHardware(u32 address, const T data) // Could just do a base-relative write, too.... TODO if ((address & 0x3E000000) == 0x08000000) { - *(T*)&m_pRAM[address & RAM_NORMAL_MASK] = data; + *(T*)GetPointerUnchecked(address) = data; } else if ((address & 0x3F800000) == 0x04000000) { *(T*)&m_pVRAM[address & VRAM_MASK] = data; @@ -122,7 +122,7 @@ inline void WriteToHardware(u32 address, const T data) *(T*)&m_pScratchPad[address & SCRATCHPAD_MASK] = data; } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { - *(T*)&m_pRAM[address & g_MemoryMask] = data; + *(T*)GetPointerUnchecked(address) = data; } else {