MemArena: Clean up the code that does the mirroring
This commit is contained in:
parent
6813473367
commit
079b881d20
|
@ -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!
|
// OK, we know where to find free space. Now grab it!
|
||||||
// We just mimic the popular BAT setup.
|
// We just mimic the popular BAT setup.
|
||||||
u32 position = 0;
|
u32 shm_position = 0;
|
||||||
u32 last_position = 0;
|
|
||||||
|
|
||||||
// Zero all the pointers to be sure.
|
// Zero all the pointers to be sure.
|
||||||
for (int i = 0; i < num_views; i++)
|
for (int i = 0; i < num_views; i++)
|
||||||
{
|
{
|
||||||
views[i].mapped_ptr = nullptr;
|
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;
|
int i;
|
||||||
for (i = 0; i < num_views; 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)
|
SKIP(flags, view->flags);
|
||||||
position = last_position;
|
|
||||||
|
|
||||||
#if _ARCH_64
|
#if _ARCH_64
|
||||||
views[i].mapped_ptr = arena->CreateView(
|
// On 64-bit, we map the same file position multiple times, so we
|
||||||
position, views[i].size, base + views[i].virtual_address);
|
// don't need the software fallback for the mirrors.
|
||||||
|
view_base = base + view->virtual_address;
|
||||||
|
use_sw_mirror = false;
|
||||||
#else
|
#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.
|
view->view_ptr = views[i - 1].view_ptr;
|
||||||
views[i].mapped_ptr = views[i - 1].mapped_ptr;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
views[i].mapped_ptr = arena->CreateView(
|
view->mapped_ptr = arena->CreateView(view->shm_position, view->size, view_base);
|
||||||
position, views[i].size, base + (views[i].virtual_address & 0x3FFFFFFF));
|
view->view_ptr = view->mapped_ptr;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (!views[i].mapped_ptr)
|
if (!view->view_ptr)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
if (views[i].out_ptr)
|
if (view->out_ptr)
|
||||||
*views[i].out_ptr = (u8*) views[i].mapped_ptr;
|
*(view->out_ptr) = (u8*) view->view_ptr;
|
||||||
|
|
||||||
position += views[i].size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -48,6 +48,8 @@ struct MemoryView
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
void* mapped_ptr;
|
void* mapped_ptr;
|
||||||
|
void* view_ptr;
|
||||||
|
u32 shm_position;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Uses a memory arena to set up an emulator-friendly memory map according to
|
// Uses a memory arena to set up an emulator-friendly memory map according to
|
||||||
|
|
Loading…
Reference in New Issue