summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2014-06-25 04:00:57 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2014-06-25 04:00:57 -0500
commita99ad2db7c78b0d0e15bf504b8dc5eb99207c608 (patch)
treeacd42e723155042954788e8b95dc90418a42a44a /Source/Core
parentf544631cc7a988bfad2cfba682a9b40b47960682 (diff)
parent31b950325d9fd354ee2310608b5c7a901256a576 (diff)
Merge pull request #499 from magumagu/ipchle-disk-channel
ES_LAUNCH fixes for disk channel etc
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/HLE/HLE.cpp4
-rw-r--r--Source/Core/Core/HLE/HLE_Misc.cpp200
-rw-r--r--Source/Core/Core/HLE/HLE_Misc.h2
-rw-r--r--Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp53
-rw-r--r--Source/Core/Core/IPC_HLE/WII_IPC_HLE.h1
-rw-r--r--Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp14
6 files changed, 42 insertions, 232 deletions
diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp
index 807eea9018..6da7028e55 100644
--- a/Source/Core/Core/HLE/HLE.cpp
+++ b/Source/Core/Core/HLE/HLE.cpp
@@ -46,10 +46,6 @@ static const SPatch OSPatches[] =
// Name doesn't matter, installed in CBoot::BootUp()
{ "HBReload", HLE_Misc::HBReload, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
- // ES_LAUNCH
- { "__OSBootDol", HLE_Misc::OSBootDol, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
- { "OSGetResetCode", HLE_Misc::OSGetResetCode, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
-
// Debug/OS Support
{ "OSPanic", HLE_OS::HLE_OSPanic, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
diff --git a/Source/Core/Core/HLE/HLE_Misc.cpp b/Source/Core/Core/HLE/HLE_Misc.cpp
index 887762c0f0..01648f8d88 100644
--- a/Source/Core/Core/HLE/HLE_Misc.cpp
+++ b/Source/Core/Core/HLE/HLE_Misc.cpp
@@ -54,206 +54,6 @@ void HBReload()
Host_Message(WM_USER_STOP);
}
-void ExecuteDOL(u8* dolFile, u32 fileSize)
-{
- // Clear memory before loading the dol
- for (u32 i = 0x80004000; i < Memory::Read_U32(0x00000034); i += 4)
- {
- // TODO: Should not write over the "save region"
- Memory::Write_U32(0x00000000, i);
- }
- CDolLoader dolLoader(dolFile, fileSize);
- dolLoader.Load();
-
- // Scan for common HLE functions
- if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
- {
- g_symbolDB.Clear();
- PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
- SignatureDB db;
- if (db.Load(File::GetSysDirectory() + TOTALDB))
- {
- db.Apply(&g_symbolDB);
- HLE::PatchFunctions();
- db.Clear();
- }
- }
-
- PowerPC::ppcState.iCache.Reset();
- TextureCache::RequestInvalidateTextureCache();
-
- CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer();
- size_t size = s_Usb->m_WiiMotes.size();
- bool* wiiMoteConnected = new bool[size];
- for (unsigned int i = 0; i < size; i++)
- wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
-
- WII_IPC_HLE_Interface::Reset(true);
- WII_IPC_HLE_Interface::Init();
- s_Usb = GetUsbPointer();
- for (unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); i++)
- {
- if (wiiMoteConnected[i])
- {
- s_Usb->m_WiiMotes[i].Activate(false);
- s_Usb->m_WiiMotes[i].Activate(true);
- }
- else
- {
- s_Usb->m_WiiMotes[i].Activate(false);
- }
- }
-
- delete[] wiiMoteConnected;
-
- if (argsPtr)
- {
- u32 args_base = Memory::Read_U32(0x800000f4);
- u32 ptr_to_num_args = 0xc;
- u32 num_args = 1;
- u32 hi_ptr = args_base + ptr_to_num_args + 4;
- u32 new_args_ptr = args_base + ptr_to_num_args + 8;
-
- Memory::Write_U32(ptr_to_num_args, args_base + 8);
- Memory::Write_U32(num_args, args_base + ptr_to_num_args);
- Memory::Write_U32(0x14, hi_ptr);
-
- for (unsigned int i = 0; i < args.length(); i++)
- Memory::WriteUnchecked_U8(args[i], new_args_ptr+i);
- }
-
- NPC = dolLoader.GetEntryPoint() | 0x80000000;
-}
-
-void LoadDOLFromDisc(std::string dol)
-{
- DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename);
- DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
-
- if (dol.length() > 1 && dol.compare(0, 1, "/") == 0)
- dol = dol.substr(1);
-
- u32 fileSize = (u32) pFileSystem->GetFileSize(dol);
- u8* dolFile = new u8[fileSize];
- if (fileSize > 0)
- {
- pFileSystem->ReadFile(dol, dolFile, fileSize);
- ExecuteDOL(dolFile, fileSize);
- }
- delete[] dolFile;
-}
-
-void LoadBootDOLFromDisc()
-{
- DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename);
- DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
- u32 fileSize = pFileSystem->GetBootDOLSize();
- u8* dolFile = new u8[fileSize];
- if (fileSize > 0)
- {
- pFileSystem->GetBootDOL(dolFile, fileSize);
- ExecuteDOL(dolFile, fileSize);
- }
- delete[] dolFile;
-}
-
-u32 GetDolFileSize(std::string dol)
-{
- DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename);
- DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
-
- std::string dolFile;
-
- if (dol.length() > 1 && dol.compare(0, 1, "/") == 0)
- dolFile = dol.substr(1);
- else
- dolFile = dol;
-
- return (u32)pFileSystem->GetFileSize(dolFile);
-}
-
-u16 GetIOSVersion()
-{
- return Memory::Read_U16(0x00003140);
-}
-
-void OSGetResetCode()
-{
- if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
- {
- u32 resetCode = Memory::Read_U32(0xCC003024);
-
- if ((resetCode & 0x1fffffff) != 0)
- {
- GPR(3) = resetCode | 0x80000000;
- }
- else
- {
- GPR(3) = 0;
- }
-
- NPC = LR;
- }
- else
- {
- HLE::UnPatch("OSGetResetCode");
- NPC = PC;
- }
-}
-
-void OSBootDol()
-{
- if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && GetIOSVersion() >= 30)
- {
- if ((GPR(4) >> 28) == 0x8)
- {
- u32 resetCode = GPR(30);
-
- // Reset game
- Memory::Write_U32(resetCode, 0xCC003024);
- LoadBootDOLFromDisc();
- return;
- }
- else if ((GPR(4) >> 28) == 0xA)
- {
- // Boot from disc partition
- PanicAlert("Boot Partition: %08x", GPR(26));
- }
- else if ((GPR(4) >> 28) == 0xC)
- {
- std::string dol;
-
- // Boot DOL from disc
- u32 ptr = GPR(28);
- Memory::GetString(dol, ptr);
-
- if (GetDolFileSize(dol) == 0)
- {
- ptr = GPR(30);
- Memory::GetString(dol, ptr);
- if (GetDolFileSize(dol) == 0)
- {
- // Cannot locate the dol file, exit.
- HLE::UnPatch("__OSBootDol");
- NPC = PC;
- return;
- }
- }
-
- argsPtr = Memory::Read_U32(GPR(5));
- Memory::GetString(args, argsPtr);
- LoadDOLFromDisc(dol);
- return;
- }
- else
- {
- PanicAlert("Unknown boot type: %08x", GPR(4));
- }
- }
- HLE::UnPatch("__OSBootDol");
- NPC = PC;
-}
-
void HLEGeckoCodehandler()
{
// Work around the codehandler not properly invalidating the icache, but
diff --git a/Source/Core/Core/HLE/HLE_Misc.h b/Source/Core/Core/HLE/HLE_Misc.h
index 3a75edb118..7647bd90d0 100644
--- a/Source/Core/Core/HLE/HLE_Misc.h
+++ b/Source/Core/Core/HLE/HLE_Misc.h
@@ -9,7 +9,5 @@ namespace HLE_Misc
void HLEPanicAlert();
void UnimplementedFunction();
void HBReload();
- void OSBootDol();
- void OSGetResetCode();
void HLEGeckoCodehandler();
}
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
index b52ae01c0b..7e2e586e87 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
@@ -76,21 +76,28 @@ IWII_IPC_HLE_Device* es_handles[ES_MAX_COUNT];
typedef std::deque<u32> ipc_msg_queue;
static ipc_msg_queue request_queue; // ppc -> arm
static ipc_msg_queue reply_queue; // arm -> ppc
+static ipc_msg_queue ack_queue; // arm -> ppc
-static int event_enqueue_reply;
-static int event_enqueue_request;
+static int event_enqueue;
static u64 last_reply_time;
-static void EnqueueReplyCallback(u64 userdata, int)
+static const u64 ENQUEUE_REQUEST_FLAG = 0x100000000ULL;
+static const u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x200000000ULL;
+static void EnqueueEventCallback(u64 userdata, int)
{
- reply_queue.push_back((u32)userdata);
- Update();
-}
-
-static void EnqueueRequestCallback(u64 userdata, int)
-{
- request_queue.push_back((u32)userdata);
+ if (userdata & ENQUEUE_ACKNOWLEDGEMENT_FLAG)
+ {
+ ack_queue.push_back((u32)userdata);
+ }
+ else if (userdata & ENQUEUE_REQUEST_FLAG)
+ {
+ request_queue.push_back((u32)userdata);
+ }
+ else
+ {
+ reply_queue.push_back((u32)userdata);
+ }
Update();
}
@@ -136,14 +143,12 @@ void Init()
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, "/dev/usb/oh1"); i++;
g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, "_Unimplemented_Device_"); i++;
- event_enqueue_reply = CoreTiming::RegisterEvent("IPCReply", EnqueueReplyCallback);
- event_enqueue_request = CoreTiming::RegisterEvent("IPCRequest", EnqueueRequestCallback);
+ event_enqueue = CoreTiming::RegisterEvent("IPCEvent", EnqueueEventCallback);
}
void Reset(bool _bHard)
{
- CoreTiming::RemoveAllEvents(event_enqueue_reply);
- CoreTiming::RemoveAllEvents(event_enqueue_request);
+ CoreTiming::RemoveAllEvents(event_enqueue);
for (IWII_IPC_HLE_Device*& dev : g_FdMap)
{
@@ -559,7 +564,7 @@ void ExecuteCommand(u32 _Address)
// Happens AS SOON AS IPC gets a new pointer!
void EnqueueRequest(u32 address)
{
- CoreTiming::ScheduleEvent(1000, event_enqueue_request, address);
+ CoreTiming::ScheduleEvent(1000, event_enqueue, address | ENQUEUE_REQUEST_FLAG);
}
// Called when IOS module has some reply
@@ -568,12 +573,18 @@ void EnqueueRequest(u32 address)
// Please search for examples of this being called elsewhere.
void EnqueueReply(u32 address, int cycles_in_future)
{
- CoreTiming::ScheduleEvent(cycles_in_future, event_enqueue_reply, address);
+ CoreTiming::ScheduleEvent(cycles_in_future, event_enqueue, address);
}
void EnqueueReply_Threadsafe(u32 address, int cycles_in_future)
{
- CoreTiming::ScheduleEvent_Threadsafe(cycles_in_future, event_enqueue_reply, address);
+ CoreTiming::ScheduleEvent_Threadsafe(cycles_in_future, event_enqueue, address);
+}
+
+void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future)
+{
+ CoreTiming::ScheduleEvent(cycles_in_future, event_enqueue,
+ address | ENQUEUE_ACKNOWLEDGEMENT_FLAG);
}
// This is called every IPC_HLE_PERIOD from SystemTimers.cpp
@@ -600,6 +611,14 @@ void Update()
reply_queue.pop_front();
return;
}
+
+ if (ack_queue.size())
+ {
+ WII_IPCInterface::GenerateAck(ack_queue.front());
+ WARN_LOG(WII_IPC_HLE, "<<-- Double-ack to IPC Request @ 0x%08x", ack_queue.front());
+ ack_queue.pop_front();
+ return;
+ }
}
void UpdateDevices()
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h
index fbb8cfb464..224dfec4bd 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.h
@@ -65,5 +65,6 @@ void ExecuteCommand(u32 _Address);
void EnqueueRequest(u32 address);
void EnqueueReply(u32 address, int cycles_in_future = 0);
void EnqueueReply_Threadsafe(u32 address, int cycles_in_future = 0);
+void EnqueueCommandAcknowledgement(u32 _Address, int cycles_in_future = 0);
} // end of namespace WII_IPC_HLE_Interface
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp
index 633364d68a..610f0dc6de 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp
@@ -394,8 +394,6 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
}
SContentAccess& rContent = itr->second;
- _dbg_assert_(WII_IPC_ES, rContent.m_pContent->m_pData != nullptr);
-
u8* pDest = Memory::GetPointer(Addr);
if (rContent.m_Position + Size > rContent.m_pContent->m_Size)
@@ -905,7 +903,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+16);
u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address+24);
-
+ std::string tContentFile;
if ((u32)(TitleID>>32) != 0x00000001 || TitleID == TITLEID_SYSMENU)
{
const DiscIO::INANDContentLoader& ContentLoader = AccessContentDevice(TitleID);
@@ -915,7 +913,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(bootInd);
if (pContent)
{
- LoadWAD(Common::GetTitleContentPath(TitleID));
+ tContentFile = Common::GetTitleContentPath(TitleID);
std::unique_ptr<CDolLoader> pDolLoader;
if (pContent->m_pData)
{
@@ -954,8 +952,6 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
for (unsigned int i = 0; i < size; i++)
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
- std::string tContentFile(m_ContentFile);
-
WII_IPC_HLE_Interface::Reset(true);
WII_IPC_HLE_Interface::Init();
s_Usb = GetUsbPointer();
@@ -997,9 +993,9 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _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
- WII_IPC_HLE_Interface::EnqueueReply(_CommandAddress, 0);
-
+ // Generate a "reply" to the IPC command. ES_LAUNCH is unique because it
+ // involves restarting IOS; IOS generates two acknowledgements in a row.
+ WII_IPC_HLE_Interface::EnqueueCommandAcknowledgement(_CommandAddress, 0);
return false;
}
break;