Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic bat #4146

Merged
merged 7 commits into from
Sep 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 0 additions & 115 deletions Source/Core/Common/MemArena.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,118 +157,3 @@ u8* MemArena::FindMemoryBase()
return static_cast<u8*>(base);
#endif
}

// yeah, this could also be done in like two bitwise ops...
#define SKIP(a_flags, b_flags) \
if (!(a_flags & MV_WII_ONLY) && (b_flags & MV_WII_ONLY)) \
continue; \
if (!(a_flags & MV_FAKE_VMEM) && (b_flags & MV_FAKE_VMEM)) \
continue;

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.

int i;
for (i = 0; i < num_views; i++)
{
MemoryView* view = &views[i];
void* view_base;
bool use_sw_mirror;

SKIP(flags, view->flags);

#if _ARCH_64
// 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
// 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))
{
view->view_ptr = views[i - 1].view_ptr;
}
else
{
view->mapped_ptr = arena->CreateView(view->shm_position, view->size, view_base);
view->view_ptr = view->mapped_ptr;
}

if (!view->view_ptr)
{
// Argh! ERROR! Free what we grabbed so far so we can try again.
MemoryMap_Shutdown(views, i + 1, flags, arena);
return false;
}

if (view->out_ptr)
*(view->out_ptr) = (u8*)view->view_ptr;
}

return true;
}

static u32 MemoryMap_InitializeViews(MemoryView* views, int num_views, u32 flags)
{
u32 shm_position = 0;
u32 last_position = 0;

for (int i = 0; i < num_views; i++)
{
// Zero all the pointers to be sure.
views[i].mapped_ptr = nullptr;

SKIP(flags, views[i].flags);

if (views[i].flags & MV_MIRROR_PREVIOUS)
shm_position = last_position;
views[i].shm_position = shm_position;
last_position = shm_position;
shm_position += views[i].size;
}

return shm_position;
}

u8* MemoryMap_Setup(MemoryView* views, int num_views, u32 flags, MemArena* arena)
{
u32 total_mem = MemoryMap_InitializeViews(views, num_views, flags);

arena->GrabSHMSegment(total_mem);

// Now, create views in high memory where there's plenty of space.
u8* base = MemArena::FindMemoryBase();
// This really shouldn't fail - in 64-bit, there will always be enough
// address space.
if (!Memory_TryBase(base, views, num_views, flags, arena))
{
PanicAlert("MemoryMap_Setup: Failed finding a memory base.");
exit(0);
return nullptr;
}

return base;
}

void MemoryMap_Shutdown(MemoryView* views, int num_views, u32 flags, MemArena* arena)
{
std::set<void*> freeset;
for (int i = 0; i < num_views; i++)
{
MemoryView* view = &views[i];
if (view->mapped_ptr && !freeset.count(view->mapped_ptr))
{
arena->ReleaseView(view->mapped_ptr, view->size);
freeset.insert(view->mapped_ptr);
view->mapped_ptr = nullptr;
}
}
}
23 changes: 0 additions & 23 deletions Source/Core/Common/MemArena.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,3 @@ class MemArena
int fd;
#endif
};

enum
{
MV_MIRROR_PREVIOUS = 1,
MV_FAKE_VMEM = 2,
MV_WII_ONLY = 4,
};

struct MemoryView
{
u8** out_ptr;
u64 virtual_address;
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
// a passed-in list of MemoryView structures.
u8* MemoryMap_Setup(MemoryView* views, int num_views, u32 flags, MemArena* arena);
void MemoryMap_Shutdown(MemoryView* views, int num_views, u32 flags, MemArena* arena);
4 changes: 4 additions & 0 deletions Source/Core/Core/Boot/Boot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ bool CBoot::Load_BS2(const std::string& _rBootROMFilename)
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
PowerPC::ppcState.spr[SPR_DBAT3U] = 0xfff0001f;
PowerPC::ppcState.spr[SPR_DBAT3L] = 0xfff00001;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();
PC = 0x81200150;
return true;
}
Expand Down Expand Up @@ -377,6 +379,8 @@ bool CBoot::BootUp()
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();

dolLoader.Load();
PC = dolLoader.GetEntryPoint();
Expand Down
12 changes: 8 additions & 4 deletions Source/Core/Core/Boot/Boot_BS2Emu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();

// Write necessary values
// Here we write values to memory that the apploader does not take care of. Game info goes
Expand Down Expand Up @@ -298,11 +300,11 @@ bool CBoot::SetupWiiMemory(DiscIO::Country country)
Memory::Write_U32(0x8179d500, 0x00003110); // Init
Memory::Write_U32(0x04000000, 0x00003118); // Unknown
Memory::Write_U32(0x04000000, 0x0000311c); // BAT
Memory::Write_U32(0x93400000, 0x00003120); // BAT
Memory::Write_U32(0x93600000, 0x00003120); // BAT
Memory::Write_U32(0x90000800, 0x00003124); // Init - MEM2 low
Memory::Write_U32(0x93ae0000, 0x00003128); // Init - MEM2 high
Memory::Write_U32(0x93ae0000, 0x00003130); // IOS MEM2 low
Memory::Write_U32(0x93b00000, 0x00003134); // IOS MEM2 high
Memory::Write_U32(0x935e0000, 0x00003128); // Init - MEM2 high
Memory::Write_U32(0x935e0000, 0x00003130); // IOS MEM2 low
Memory::Write_U32(0x93600000, 0x00003134); // IOS MEM2 high
Memory::Write_U32(0x00000012, 0x00003138); // Console type
// 40 is copied from 88 after running apploader
Memory::Write_U32(0x00090204, 0x00003140); // IOS revision (IOS9, v2.4)
Expand Down Expand Up @@ -371,6 +373,8 @@ bool CBoot::EmulatedBS2_Wii()
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();

Memory::Write_U32(0x4c000064, 0x00000300); // Write default DSI Handler: rfi
Memory::Write_U32(0x4c000064, 0x00000800); // Write default FPU Handler: rfi
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/Boot/Boot_ELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ bool CBoot::Boot_ELF(const std::string& filename)
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();

if (!reader.LoadSymbols())
{
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/FifoPlayer/FifoPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ void FifoPlayer::LoadMemory()
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();

SetupFifo();

Expand Down
Loading