2017-10-16 11:55:29 +02:00
# include <stdio.h>
# include <stdlib.h>
# include <ogcsys.h>
# include "sys.h"
2024-02-13 03:19:57 +01:00
# include "malloc.h"
2017-10-16 11:55:29 +02:00
# include "mload.h"
# include "ehcmodule_elf.h"
/* Constants */
2024-02-13 03:19:57 +01:00
# define CERTS_LEN 0x280
2017-10-16 11:55:29 +02:00
/* Variables */
static const char certs_fs [ ] ATTRIBUTE_ALIGN ( 32 ) = " /sys/cert.sys " ;
2022-04-19 12:39:21 +02:00
u32 boot2version ;
2023-02-19 21:21:09 +01:00
static bool gDisablePRButtons = false ;
2022-04-19 12:39:21 +02:00
void __Sys_ResetCallback ( __attribute__ ( ( unused ) ) u32 irq , __attribute__ ( ( unused ) ) void * ctx )
2017-10-16 11:55:29 +02:00
{
/* Reboot console */
2023-02-19 21:21:09 +01:00
if ( ! gDisablePRButtons )
Sys_Reboot ( ) ;
2017-10-16 11:55:29 +02:00
}
void __Sys_PowerCallback ( void )
{
/* Poweroff console */
2023-02-19 21:21:09 +01:00
if ( ! gDisablePRButtons )
Sys_Shutdown ( ) ;
2017-10-16 11:55:29 +02:00
}
2024-03-01 15:31:12 +01:00
bool tmdIsStubIOS ( tmd * p_tmd )
{
return
p_tmd - > sys_version > > 32 = = 0
& & p_tmd - > num_contents = = 3
& & p_tmd - > contents [ 0 ] . type = = 0x0001
& & p_tmd - > contents [ 1 ] . type = = 0x8001
& & p_tmd - > contents [ 2 ] . type = = 0x8001 ;
}
2024-02-13 03:19:57 +01:00
bool isIOSstub ( u8 ios_number )
{
u32 tmd_size = 0 ;
tmd_view * ios_tmd ;
if ( ( boot2version > = 5 ) & & ( ios_number = = 202 | | ios_number = = 222 | | ios_number = = 223 | | ios_number = = 224 ) )
return true ;
ES_GetTMDViewSize ( 0x0000000100000000ULL | ios_number , & tmd_size ) ;
if ( ! tmd_size )
{
// getting size failed. invalid or fake tmd for sure!
// gprintf("failed to get tmd for ios %d\n",ios_number);
return true ;
}
ios_tmd = memalign32 ( tmd_size ) ;
if ( ! ios_tmd )
{
// gprintf("failed to mem align the TMD struct!\n");
return true ;
}
memset ( ios_tmd , 0 , tmd_size ) ;
ES_GetTMDView ( 0x0000000100000000ULL | ios_number , ( u8 * ) ios_tmd , tmd_size ) ;
// gprintf("IOS %d is rev %d(0x%x) with tmd size of %u and %u contents\n",ios_number,ios_tmd->title_version,ios_tmd->title_version,tmd_size,ios_tmd->num_contents);
/*Stubs have a few things in common:
- title version : it is mostly 65280 , or even better : in hex the last 2 digits are 0.
example : IOS 60 rev 6400 = 0x1900 = 00 = stub
- exception for IOS21 which is active , the tmd size is 592 bytes ( or 140 with the views )
- the stub ios ' have 1 app of their own ( type 0x1 ) and 2 shared apps ( type 0x8001 ) .
eventho the 00 check seems to work fine , we ' ll only use other knowledge as well cause some
people / applications install an ios with a stub rev > _ > . . . */
u8 Version = ios_tmd - > title_version ;
if ( ( boot2version > = 5 ) & & ( ios_number = = 249 | | ios_number = = 250 ) & & ( Version < 18 ) )
return true ;
if ( ( ios_number = = 202 | | ios_number = = 222 | | ios_number = = 223 | | ios_number = = 224 ) & & ( Version < 4 ) )
return true ;
// version now contains the last 2 bytes. as said above, if this is 00, its a stub
if ( Version = = 0 )
{
if ( ( ios_tmd - > num_contents = = 3 ) & & ( ios_tmd - > contents [ 0 ] . type = = 1 & & ios_tmd - > contents [ 1 ] . type = = 0x8001 & & ios_tmd - > contents [ 2 ] . type = = 0x8001 ) )
{
// gprintf("IOS %d is a stub\n",ios_number);
free ( ios_tmd ) ;
return true ;
}
else
{
// gprintf("IOS %d is active\n",ios_number);
free ( ios_tmd ) ;
return false ;
}
}
// gprintf("IOS %d is active\n",ios_number);
free ( ios_tmd ) ;
return false ;
}
2017-10-16 11:55:29 +02:00
bool loadIOS ( int ios )
{
2024-02-13 03:19:57 +01:00
if ( isIOSstub ( ios ) )
return false ;
2017-10-16 11:55:29 +02:00
mload_close ( ) ;
2024-02-13 03:19:57 +01:00
if ( IOS_ReloadIOS ( ios ) > = 0 )
2017-10-16 11:55:29 +02:00
{
if ( IOS_GetVersion ( ) ! = 249 & & IOS_GetVersion ( ) ! = 250 )
{
if ( mload_init ( ) > = 0 )
{
data_elf my_data_elf ;
2024-02-13 03:19:57 +01:00
mload_elf ( ( void * ) ehcmodule_elf , & my_data_elf ) ;
2017-10-16 11:55:29 +02:00
mload_run_thread ( my_data_elf . start , my_data_elf . stack , my_data_elf . size_stack , 0x47 ) ;
}
}
return true ;
}
return false ;
}
void Sys_Init ( void )
{
/* Initialize video subsytem */
VIDEO_Init ( ) ;
/* Set RESET/POWER button callback */
SYS_SetResetCallback ( __Sys_ResetCallback ) ;
SYS_SetPowerCallback ( __Sys_PowerCallback ) ;
}
void Sys_Reboot ( void )
{
/* Restart console */
STM_RebootSystem ( ) ;
}
void Sys_Shutdown ( void )
{
/* Poweroff console */
2024-02-13 03:19:57 +01:00
if ( CONF_GetShutdownMode ( ) = = CONF_SHUTDOWN_IDLE )
{
2017-10-16 11:55:29 +02:00
s32 ret ;
/* Set LED mode */
ret = CONF_GetIdleLedMode ( ) ;
2024-02-13 03:19:57 +01:00
if ( ret > = 0 & & ret < = 2 )
2017-10-16 11:55:29 +02:00
STM_SetLedMode ( ret ) ;
/* Shutdown to idle */
STM_ShutdownToIdle ( ) ;
2024-02-13 03:19:57 +01:00
}
else
{
2017-10-16 11:55:29 +02:00
/* Shutdown to standby */
STM_ShutdownToStandby ( ) ;
}
}
void Sys_LoadMenu ( void )
{
2024-03-02 00:07:58 +01:00
/* SYSCALL(exit) does all of this already */
exit ( 0 ) ;
/* Also the code gcc generated for this looks really painful */
#if 0
2017-10-16 11:55:29 +02:00
int HBC = 0 ;
2024-02-13 03:19:57 +01:00
char * sig = ( char * ) 0x80001804 ;
if ( sig [ 0 ] = = ' S ' & &
sig [ 1 ] = = ' T ' & &
sig [ 2 ] = = ' U ' & &
sig [ 3 ] = = ' B ' & &
sig [ 4 ] = = ' H ' & &
sig [ 5 ] = = ' A ' & &
sig [ 6 ] = = ' X ' & &
sig [ 7 ] = = ' X ' )
2017-10-16 11:55:29 +02:00
{
2024-02-13 03:19:57 +01:00
HBC = 1 ; // Exit to HBC
2017-10-16 11:55:29 +02:00
}
/* Homebrew Channel stub */
2024-02-13 03:19:57 +01:00
if ( HBC = = 1 )
{
2017-10-16 11:55:29 +02:00
exit ( 0 ) ;
}
/* Return to the Wii system menu */
SYS_ResetSystem ( SYS_RETURNTOMENU , 0 , 0 ) ;
2024-03-02 00:07:58 +01:00
# endif
2017-10-16 11:55:29 +02:00
}
s32 Sys_GetCerts ( signed_blob * * certs , u32 * len )
{
static signed_blob certificates [ CERTS_LEN ] ATTRIBUTE_ALIGN ( 32 ) ;
s32 fd , ret ;
/* Open certificates file */
fd = IOS_Open ( certs_fs , 1 ) ;
if ( fd < 0 )
return fd ;
/* Read certificates */
ret = IOS_Read ( fd , certificates , sizeof ( certificates ) ) ;
/* Close file */
IOS_Close ( fd ) ;
/* Set values */
2024-02-13 03:19:57 +01:00
if ( ret > 0 )
{
2017-10-16 11:55:29 +02:00
* certs = certificates ;
2024-02-13 03:19:57 +01:00
* len = sizeof ( certificates ) ;
2017-10-16 11:55:29 +02:00
}
return ret ;
}
2023-02-19 21:21:09 +01:00
void SetPRButtons ( bool enabled )
{
gDisablePRButtons = ! enabled ;
}