Use additional memory map mirrors for 32-bit.

Well, use them always for simplicity, but this works around 32-bit
limitations on mmap() size for Android and Linux.
This commit is contained in:
Unknown W. Brackets 2013-12-10 08:25:38 -08:00
parent be777fc535
commit 5b0ece85da
5 changed files with 45 additions and 9 deletions

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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
{