2010-09-24 15:46:32 +02:00
|
|
|
#include <gctypes.h>
|
|
|
|
|
|
|
|
#include "IosLoader.h"
|
|
|
|
#include "../fatmounter.h"
|
|
|
|
#include "../usbloader/usbstorage2.h"
|
2010-10-27 16:45:27 +02:00
|
|
|
#include "../usbloader/disc.h"
|
2010-11-06 16:30:14 +01:00
|
|
|
#include "../usbloader/wdvd.h"
|
2010-09-24 15:46:32 +02:00
|
|
|
#include "../wad/nandtitle.h"
|
|
|
|
#include "../mload/mload_modules.h"
|
|
|
|
#include "../settings/CSettings.h"
|
|
|
|
#include "wad/nandtitle.h"
|
2010-10-01 17:01:19 +02:00
|
|
|
#include "mload/mload.h"
|
|
|
|
#include "mload/modules/ehcmodule_5.h"
|
|
|
|
#include "mload/modules/dip_plugin_249.h"
|
|
|
|
#include "mload/modules/odip_frag.h"
|
2010-11-07 13:16:34 +01:00
|
|
|
#include "gecko.h"
|
2010-10-01 17:01:19 +02:00
|
|
|
|
2010-09-24 15:46:32 +02:00
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* Public Methods:
|
|
|
|
******************************************************************************/
|
2010-11-07 13:16:34 +01:00
|
|
|
/*
|
|
|
|
* Check if the ios passed is a Hermes ios.
|
|
|
|
*/
|
|
|
|
bool IosLoader::IsHermesIOS(s32 ios)
|
|
|
|
{
|
|
|
|
return (ios == 222 || ios == 223 || ios == 224 || ios == 202);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the ios passed is a Waninkoko ios.
|
|
|
|
*/
|
|
|
|
bool IosLoader::IsWaninkokoIOS(s32 ios)
|
|
|
|
{
|
|
|
|
if(ios < 200 || ios > 255)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return !IsHermesIOS(ios);
|
|
|
|
}
|
|
|
|
|
2010-09-24 15:46:32 +02:00
|
|
|
/*
|
|
|
|
* Loads CIOS (If possible the one from the settings file).
|
|
|
|
* @return 0 if a cios has been successfully loaded. Else a value below 0 is returned.
|
|
|
|
*/
|
|
|
|
s32 IosLoader::LoadAppCios()
|
|
|
|
{
|
2010-11-28 16:31:08 +01:00
|
|
|
u32 activeCios = IOS_GetVersion();
|
2010-09-24 15:46:32 +02:00
|
|
|
s32 ret = -1;
|
|
|
|
|
2010-11-28 16:31:08 +01:00
|
|
|
// We have what we need
|
|
|
|
if((int) activeCios == Settings.cios)
|
|
|
|
return 0;
|
|
|
|
|
2010-10-01 17:01:19 +02:00
|
|
|
// Unmount fat before reloading IOS.
|
2010-09-24 15:46:32 +02:00
|
|
|
SDCard_deInit();
|
|
|
|
USBDevice_deInit();
|
2010-11-28 16:31:08 +01:00
|
|
|
__io_usbstorage.shutdown();
|
|
|
|
USB_Deinitialize();
|
2010-09-24 15:46:32 +02:00
|
|
|
|
2010-11-28 16:31:08 +01:00
|
|
|
u32 ciosLoadPriority[] = { 250, 222, 249, Settings.cios }; // Descending.
|
2010-09-24 15:46:32 +02:00
|
|
|
|
|
|
|
|
2010-09-24 17:54:06 +02:00
|
|
|
for (u8 i = (sizeof(ciosLoadPriority)/sizeof(ciosLoadPriority[0]))-1; i >= 0; i--)
|
2010-09-24 15:46:32 +02:00
|
|
|
{
|
|
|
|
u32 cios = ciosLoadPriority[i];
|
|
|
|
|
|
|
|
if (activeCios == cios)
|
|
|
|
{
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ret = ReloadIosSafe(cios)) > -1)
|
|
|
|
{
|
|
|
|
// Remember working cios.
|
|
|
|
Settings.cios = cios;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-11-06 16:30:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Loads a CIOS before a game start.
|
|
|
|
* @return 0 if a cios has been successfully loaded. Else a value below 0 is returned.
|
|
|
|
*/
|
|
|
|
s32 IosLoader::LoadGameCios(s32 ios)
|
|
|
|
{
|
|
|
|
if(ios == IOS_GetVersion())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
s32 ret = -1;
|
|
|
|
|
|
|
|
// Unmount fat before reloading IOS.
|
|
|
|
SDCard_deInit();
|
|
|
|
USBDevice_deInit();
|
|
|
|
WDVD_Close();
|
|
|
|
__io_usbstorage.shutdown(); // libogc usb
|
|
|
|
__io_usbstorage2.shutdown(); // cios usb
|
|
|
|
USB_Deinitialize(); // main usb handle
|
|
|
|
|
|
|
|
ret = ReloadIosSafe(ios);
|
|
|
|
|
|
|
|
// Remount devices after reloading IOS.
|
|
|
|
SDCard_Init();
|
|
|
|
USBDevice_Init();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-09-24 15:46:32 +02:00
|
|
|
/*
|
|
|
|
* Reloads a certain IOS under the condition, that an appropriate version of the IOS is installed.
|
|
|
|
* @return a negative value if a safe reload of the ios was not possible.
|
|
|
|
*/
|
|
|
|
s32 IosLoader::ReloadIosSafe(s32 ios)
|
|
|
|
{
|
2010-11-07 13:16:34 +01:00
|
|
|
if(IsHermesIOS(ios))
|
2010-09-24 15:46:32 +02:00
|
|
|
{
|
2010-11-07 13:16:34 +01:00
|
|
|
s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
|
2010-11-07 21:31:45 +01:00
|
|
|
if(iosRev != 4 && iosRev != 5 && iosRev != 65535)
|
2010-11-07 13:16:34 +01:00
|
|
|
return -11;
|
|
|
|
}
|
|
|
|
else if(IsWaninkokoIOS(ios))
|
|
|
|
{
|
|
|
|
s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
|
|
|
|
if(iosRev < 9 || iosRev > 30) //let's see if Waninkoko actually gets to 30
|
|
|
|
return -22;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return -33;
|
2010-09-24 15:46:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
s32 r = IOS_ReloadIOS(ios);
|
|
|
|
if (r >= 0) WII_Initialize();
|
2010-10-01 17:01:19 +02:00
|
|
|
|
|
|
|
IosLoader::LoadIOSModules(IOS_GetVersion(), IOS_GetRevision());
|
|
|
|
|
2010-09-24 15:46:32 +02:00
|
|
|
return r;
|
|
|
|
}
|
2010-10-01 17:01:19 +02:00
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* Private/Protected Methods:
|
|
|
|
******************************************************************************/
|
|
|
|
void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
|
|
|
|
{
|
|
|
|
//! Hermes IOS
|
2010-11-07 13:16:34 +01:00
|
|
|
if(IsHermesIOS(ios))
|
2010-10-01 17:01:19 +02:00
|
|
|
{
|
|
|
|
const u8 * ech_module = NULL;
|
|
|
|
int ehc_module_size = 0;
|
|
|
|
const u8 * dip_plugin = NULL;
|
|
|
|
int dip_plugin_size = 0;
|
|
|
|
|
2010-11-07 21:31:45 +01:00
|
|
|
ech_module = ehcmodule_5;
|
|
|
|
ehc_module_size = ehcmodule_5_size;
|
|
|
|
dip_plugin = odip_frag;
|
|
|
|
dip_plugin_size = odip_frag_size;
|
|
|
|
gprintf("Loading ehc v5 and opendip module\n");
|
2010-10-01 17:01:19 +02:00
|
|
|
|
|
|
|
u8 *ehc_cfg = search_for_ehcmodule_cfg((u8 *) ech_module, ehc_module_size);
|
|
|
|
if (ehc_cfg)
|
|
|
|
{
|
|
|
|
ehc_cfg += 12;
|
|
|
|
ehc_cfg[0] = 0; // USB Port 0
|
2010-11-07 13:16:34 +01:00
|
|
|
gprintf("Patched ehc module to use usb port 0.\n");
|
2010-10-01 17:01:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
load_modules(ech_module, ehc_module_size, dip_plugin, dip_plugin_size);
|
|
|
|
}
|
|
|
|
//! Waninkoko IOS
|
2010-11-07 13:16:34 +01:00
|
|
|
else if(IsWaninkokoIOS(ios))
|
2010-10-01 17:01:19 +02:00
|
|
|
{
|
|
|
|
if(ios_rev >= 18)
|
|
|
|
{
|
|
|
|
if(mload_init() < 0)
|
|
|
|
return;
|
|
|
|
|
2010-11-07 13:16:34 +01:00
|
|
|
gprintf("Loading dip module for Waninkoko's cios\n");
|
2010-10-01 17:01:19 +02:00
|
|
|
mload_module((u8 *) dip_plugin_249, dip_plugin_249_size);
|
|
|
|
mload_close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|