Merge pull request #4468 from marcan/master

Make the neutered version of HBC work in Dolphin
This commit is contained in:
Anthony 2016-11-30 16:39:53 -06:00 committed by GitHub
commit a3d2dead76
7 changed files with 44 additions and 15 deletions

View File

@ -381,6 +381,8 @@ bool CBoot::BootUp()
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
if (dolLoader.IsWii())
HID4.SBE = 1;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();

View File

@ -35,12 +35,12 @@ bool CBoot::IsElfWii(const std::string& filename)
u32 HID4_mask = Common::swap32(0xfc1fffff);
ElfReader reader(elf.get());
for (int i = 0; i < reader.GetNumSections(); ++i)
for (int i = 0; i < reader.GetNumSegments(); ++i)
{
if (reader.IsCodeSection(i))
if (reader.IsCodeSegment(i))
{
u32* code = (u32*)reader.GetSectionDataPtr(i);
for (u32 j = 0; j < reader.GetSectionSize(i) / sizeof(u32); ++j)
u32* code = (u32*)reader.GetSegmentPtr(i);
for (u32 j = 0; j < reader.GetSegmentSize(i) / sizeof(u32); ++j)
{
if ((code[j] & HID4_mask) == HID4_pattern)
return true;
@ -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;
if (IsElfWii(filename))
HID4.SBE = 1;
PowerPC::DBATUpdated();
PowerPC::IBATUpdated();

View File

@ -109,7 +109,11 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
return false;
pDolLoader->Load();
PC = pDolLoader->GetEntryPoint();
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
// The state of other CPU registers (like the BAT registers) doesn't matter much
// because the realmode code at 0x3400 initializes everything itself anyway.
MSR = 0;
PC = 0x3400;
// Pass the "#002 check"
// Apploader should write the IOS version and revision to 0x3140, and compare it

View File

@ -55,8 +55,9 @@ public:
else
return nullptr;
}
bool IsCodeSection(int section) const { return sections[section].sh_type == SHT_PROGBITS; }
bool IsCodeSegment(int segment) const { return segments[segment].p_flags & PF_X; }
const u8* GetSegmentPtr(int segment) { return GetPtr(segments[segment].p_offset); }
int GetSegmentSize(int segment) const { return segments[segment].p_filesz; }
u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found

View File

@ -533,6 +533,11 @@ void ExecuteCommand(u32 address)
{
result = device->IOCtl(address);
}
else
{
Memory::Write_U32(FS_EINVAL, address + 4);
result = IWII_IPC_HLE_Device::GetDefaultReply();
}
break;
}
case IPC_CMD_IOCTLV:
@ -541,6 +546,11 @@ void ExecuteCommand(u32 address)
{
result = device->IOCtlV(address);
}
else
{
Memory::Write_U32(FS_EINVAL, address + 4);
result = IWII_IPC_HLE_Device::GetDefaultReply();
}
break;
}
default:

View File

@ -937,6 +937,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{
_dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2);
bool bSuccess = false;
bool bReset = false;
u16 IOSv = 0xffff;
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
@ -968,13 +969,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
if (pDolLoader->IsValid())
{
pDolLoader->Load(); // TODO: Check why sysmenu does not load the DOL correctly
// WADs start with address translation off at the given entry point.
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
//
// The state of other CPU registers (like the BAT registers) doesn't matter much
// because the WAD initializes everything itself anyway.
// because the realmode code at 0x3400 initializes everything itself anyway.
MSR = 0;
PC = pDolLoader->GetEntryPoint();
PC = 0x3400;
bSuccess = true;
bReset = true;
}
else
{
@ -1045,7 +1047,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188);
// TODO: provide correct return code when bSuccess= false
Memory::Write_U32(0, _CommandAddress + 0x4);
// Note: If we just reset the PPC, don't write anything to the command buffer. This
// could clobber the DOL we just loaded.
if (!bReset)
{
Memory::Write_U32(0, _CommandAddress + 0x4);
}
ERROR_LOG(WII_IPC_ES,
"IOCTL_ES_LAUNCH %016" PRIx64 " %08x %016" PRIx64 " %08x %016" PRIx64 " %04x",
@ -1055,10 +1062,13 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
// This is necessary because Reset(true) above deleted this object. Ew.
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, _CommandAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8);
if (!bReset)
{
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, _CommandAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8);
}
// Generate a "reply" to the IPC command. ES_LAUNCH is unique because it
// involves restarting IOS; IOS generates two acknowledgements in a row.

View File

@ -50,7 +50,7 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(u32 command_address)
IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 command_address)
{
IPCCommandResult reply = GetNoReply();
IPCCommandResult reply = GetDefaultReply();
u32 command = Memory::Read_U32(command_address + 0x0c);
u32 buffer_in = Memory::Read_U32(command_address + 0x10);
u32 buffer_in_size = Memory::Read_U32(command_address + 0x14);