s32 __IOS_LaunchNewIOS(int version) { u32 numviews; s32 res; u64 titleID = 0x100000000LL; raw_irq_handler_t irq_handler; u32 counter; STACK_ALIGN(tikview,views,4,32); #ifdef DEBUG_IOS s32 oldversion; #endif s32 newversion; if(version < 3 || version > 0xFF) { return IOS_EBADVERSION; } #ifdef DEBUG_IOS oldversion = IOS_GetVersion(); if(oldversion>0) printf("Current IOS Version: IOS%d\n",oldversion); #endif titleID |= version; #ifdef DEBUG_IOS printf("Launching IOS TitleID: %016llx\n",titleID); #endif res = ES_GetNumTicketViews(titleID, &numviews); if(res < 0) { #ifdef DEBUG_IOS printf(" GetNumTicketViews failed: %d\n",res); #endif return res; } if(numviews > 4) { printf(" GetNumTicketViews too many views: %lu\n",numviews); return IOS_ETOOMANYVIEWS; } res = ES_GetTicketViews(titleID, views, numviews); if(res < 0) { #ifdef DEBUG_IOS printf(" GetTicketViews failed: %d\n",res); #endif return res; } write32(0x80003140, 0); res = ES_LaunchTitleBackground(titleID, &views[0]); if(res < 0) { #ifdef DEBUG_IOS printf(" LaunchTitleBackground failed: %d\n",res); #endif return res; } __ES_Reset(); // Mask IPC IRQ while we're busy reloading __MaskIrq(IRQ_PI_ACR); irq_handler = IRQ_Free(IRQ_PI_ACR); #ifdef DEBUG_IOS printf("Waiting for IOS ...\n"); #endif while ((read32(0x80003140) >> 16) == 0) udelay(1000); #ifdef DEBUG_IOS u32 v = read32(0x80003140); printf("IOS loaded: IOS%d v%d.%d\n", v >> 16, (v >> 8) & 0xff, v & 0xff); #endif #ifdef DEBUG_IOS printf("Waiting for IPC ...\n"); #endif for (counter = 0; !(read32(0x0d000004) & 2); counter++) { udelay(1000); if (counter >= MAX_IPC_RETRIES) break; } #ifdef DEBUG_IOS printf("IPC started (%u)\n", counter); #endif IRQ_Request(IRQ_PI_ACR, irq_handler, NULL); __UnmaskIrq(IRQ_PI_ACR); __IPC_Reinitialize(); newversion = IOS_GetVersion(); if(newversion != version) { #ifdef DEBUG_IOS printf(" Version mismatch!\n"); #endif return IOS_EMISMATCH; } return version; }
s32 __DI_StubLaunch(void) { u64 titleID = DVD_TITLEID; static tikview views[4] ATTRIBUTE_ALIGN(32); u32 numviews; s32 res; u32 ints; dprintf("Shutting down IOS subsystems\n"); res = __IOS_ShutdownSubsystems(); if(res < 0) { dprintf("Shutdown failed: %d\n",res); } dprintf("Initializing ES\n"); res = __ES_Init(); if(res < 0) { dprintf("ES init failed: %d\n",res); return res; } dprintf("Launching TitleID: %016llx\n",titleID); res = ES_GetNumTicketViews(titleID, &numviews); if(res < 0) { dprintf(" GetNumTicketViews failed: %d\n",res); return res; } if(numviews > 4) { dprintf(" GetNumTicketViews too many views: %u\n",numviews); return IOS_ETOOMANYVIEWS; } res = ES_GetTicketViews(titleID, views, numviews); if(res < 0) { dprintf(" GetTicketViews failed: %d\n",res); return res; } dprintf("Ready to launch channel\n"); res = ES_LaunchTitleBackground(titleID, &views[0]); if(res<0) { dprintf("Launch failed: %d\n",res); return res; } dprintf("Channel launching in the background\n"); dprintf("Pre-stub status:\n"); dumpregs(); dprintf("ISR Disable...\n"); _CPU_ISR_Disable( ints ); dprintf("Saving regs...\n"); __distub_saveregs(); dprintf("Taking the plunge...\n"); __distub_take_plunge(&di_ctx); dprintf("We're back!\n"); dprintf("Restoring regs...\n"); __distub_restregs(); dprintf("ISR Enable...\n"); _CPU_ISR_Restore( ints ); dprintf("Post-stub status:\n"); dumpregs(); __IPC_Reinitialize(); __ES_Reset(); dprintf("IPC reinitialized\n"); sleep(1); dprintf("Restarting IOS subsystems\n"); res = __IOS_InitializeSubsystems(); dprintf("Subsystems running!\n"); res = ES_GetNumTicketViews(titleID, &numviews); if(res < 0) { dprintf(" GetNumTicketViews failed: %d\n",res); return res; } dprintf(" GetNumTicketViews: %d",numviews); return 0; }