mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-21 08:14:48 +00:00
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:
parent
be777fc535
commit
5b0ece85da
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user