Пример #1
0
/* Run given thread until it reaches address stopat. */
bool fncall_runtil(thread_t * thread, address_t stopat) {

    /* TODO: Be more verbose about errors. */
    insn_t          insn;
    insn_kind_t     kind;
    
    assert(!thread->state.slavemode);
    
    info("Running thread %s until it reaches %p (runtil).", str_thread(thread), (void *) stopat);
    
    thread->state.slavemode = true;
    
    kind = (stopat & 0x1) ? INSN_KIND_THUMB : INSN_KIND_ARM;
    if (!patch_read_insn_detect_kind(thread, stopat, &insn, &kind))
        goto fail;
        
    /* Patch instruction. */
    if (!patch_insn(thread, stopat, kind, get_breakpoint_insn(kind)))
        goto fail;
        
    thread_continue(thread, 0);
    
    while (1) {
        thread_wait(thread, false);
        
        if (thread->state.dead)
            goto fail;
            
        if ((thread->state.signo == SIGSEGV) || (thread->state.signo == SIGTRAP) || (thread->state.signo == SIGBUS)) {
            struct pt_regs regs;
            thread_get_regs(thread, &regs);
            if (arch_get_pc(&regs) == (stopat & 0xfffffffe)) {
                /* This is the signal we were waiting for. */
                break;
            }
        }
        
        warning("Unexpected signal %s received during runtil in thread %s. The signal will be delivered.",
                str_signal(thread->state.signo), str_thread(thread));

        dump_thread(thread);
        void callback(segment_t * segment) {
            verbose("%s\n", str_segment(segment));
        }
        segment_iter(thread->process, callback);

        /* Deliver the signal. */
        thread_continue(thread, 0);
    }
Пример #2
0
int _main( int argc, char *argv[] )
{
	//BSS is in DATA section so IOS doesnt touch it, we need to manually clear it
	//dbgprintf("memset32(%08x, 0, %08x)\n", &__bss_start, &__bss_end - &__bss_start);
	memset32(&__bss_start, 0, &__bss_end - &__bss_start);
	sync_after_write(&__bss_start, &__bss_end - &__bss_start);

	s32 ret = 0;
	u32 DI_Thread = 0;

	u8 MessageHeap[0x10];

	BootStatus(0, 0, 0);

	thread_set_priority( 0, 0x79 );	// do not remove this, this waits for FS to be ready!
	thread_set_priority( 0, 0x50 );
	thread_set_priority( 0, 0x79 );

//Disable AHBPROT
	EnableAHBProt(-1);

//Load IOS Modules
	ES_Init( MessageHeap );

//Early HID for loader
	HIDInit();

//Enable DVD Access
	write32(HW_DIFLAGS, read32(HW_DIFLAGS) & ~DI_DISABLEDVD);

	dbgprintf("Sending signal to loader\r\n");
	BootStatus(1, 0, 0);
	mdelay(10);

//Loader running, selects games
	while(1)
	{
		sync_before_read((void*)RESET_STATUS, 0x20);
		vu32 reset_status = read32(RESET_STATUS);
		if(reset_status != 0)
		{
			if(reset_status == 0x0DEA)
				break; //game selected
			else if(reset_status == 0x1DEA)
				goto DoIOSBoot; //exit
			write32(RESET_STATUS, 0);
			sync_after_write((void*)RESET_STATUS, 0x20);
		}
		HIDUpdateRegisters(1);
		mdelay(10);
	}
	ConfigSyncBeforeRead();

	u32 UseUSB = ConfigGetConfig(NIN_CFG_USB);
	SetDiskFunctions(UseUSB);

	BootStatus(2, 0, 0);
	if(UseUSB)
	{
		ret = USBStorage_Startup();
		dbgprintf("USB:Drive size: %dMB SectorSize:%d\r\n", s_cnt / 1024 * s_size / 1024, s_size);
	}
	else
	{
		s_size = PAGE_SIZE512; //manually set s_size
		ret = SDHCInit();
	}
	if(ret != 1)
	{
		dbgprintf("Device Init failed:%d\r\n", ret );
		BootStatusError(-2, ret);
		mdelay(4000);
		Shutdown();
	}

	//Verification if we can read from disc
	if(memcmp(ConfigGetGamePath(), "di", 3) == 0)
		RealDI_Init(); //will shutdown on fail

	BootStatus(3, 0, 0);
	fatfs = (FATFS*)malloca( sizeof(FATFS), 32 );

	s32 res = f_mount( fatfs, fatDevName, 1 );
	if( res != FR_OK )
	{
		dbgprintf("ES:f_mount() failed:%d\r\n", res );
		BootStatusError(-3, res);
		mdelay(4000);
		Shutdown();
	}
	
	BootStatus(4, 0, 0);

	BootStatus(5, 0, 0);

	FIL fp;
	s32 fres = f_open_char(&fp, "/bladie", FA_READ|FA_OPEN_EXISTING);
	switch(fres)
	{
		case FR_OK:
			f_close(&fp);
		case FR_NO_PATH:
		case FR_NO_FILE:
		{
			fres = FR_OK;
		} break;
		default:
		case FR_DISK_ERR:
		{
			BootStatusError(-5, fres);
			mdelay(4000);
			Shutdown();
		} break;
	}

	if(!UseUSB) //Use FAT values for SD
		s_cnt = fatfs->n_fatent * fatfs->csize;

	BootStatus(6, s_size, s_cnt);

	BootStatus(7, s_size, s_cnt);
	ConfigInit();

	if (ConfigGetConfig(NIN_CFG_LOG))
		SDisInit = 1;  // Looks okay after threading fix
	dbgprintf("Game path: %s\r\n", ConfigGetGamePath());

	BootStatus(8, s_size, s_cnt);

	memset32((void*)RESET_STATUS, 0, 0x20);
	sync_after_write((void*)RESET_STATUS, 0x20);

	memset32((void*)0x13002800, 0, 0x30);
	sync_after_write((void*)0x13002800, 0x30);
	memset32((void*)0x13160000, 0, 0x20);
	sync_after_write((void*)0x13160000, 0x20);

	memset32((void*)0x13026500, 0, 0x100);
	sync_after_write((void*)0x13026500, 0x100);

	BootStatus(9, s_size, s_cnt);

	DIRegister();
	DI_Thread = thread_create(DIReadThread, NULL, ((u32*)&__di_stack_addr), ((u32)(&__di_stack_size)) / sizeof(u32), 0x78, 1);
	thread_continue(DI_Thread);

	DIinit(true);

	BootStatus(10, s_size, s_cnt);

	GCAMInit();

	EXIInit();

	BootStatus(11, s_size, s_cnt);

	SIInit();
	StreamInit();

	PatchInit();
//Tell PPC side we are ready!
	cc_ahbMemFlush(1);
	mdelay(1000);
	BootStatus(0xdeadbeef, s_size, s_cnt);
	mdelay(1000); //wait before hw flag changes
	dbgprintf("Kernel Start\r\n");

	//write32( 0x1860, 0xdeadbeef );	// Clear OSReport area
	//sync_after_write((void*)0x1860, 0x20);

	u32 Now = read32(HW_TIMER);
	u32 PADTimer = Now;
	u32 DiscChangeTimer = Now;
	u32 ResetTimer = Now;
	u32 InterruptTimer = Now;
	USBReadTimer = Now;
	u32 Reset = 0;
	bool SaveCard = false;
	if( ConfigGetConfig(NIN_CFG_LED) )
	{
		set32(HW_GPIO_ENABLE, GPIO_SLOT_LED);
		clear32(HW_GPIO_DIR, GPIO_SLOT_LED);
		clear32(HW_GPIO_OWNER, GPIO_SLOT_LED);
	}
	set32(HW_GPIO_ENABLE, GPIO_SENSOR_BAR);
	clear32(HW_GPIO_DIR, GPIO_SENSOR_BAR);
	clear32(HW_GPIO_OWNER, GPIO_SENSOR_BAR);
	set32(HW_GPIO_OUT, GPIO_SENSOR_BAR);	//turn on sensor bar

	write32( HW_PPCIRQMASK, (1<<30) );
	write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) );

//This bit seems to be different on japanese consoles
	u32 ori_ppcspeed = read32(HW_PPCSPEED);
	if((ConfigGetGameID() & 0xFF) == 'J')
		set32(HW_PPCSPEED, (1<<17));
	else
		clear32(HW_PPCSPEED, (1<<17));

	u32 ori_widesetting = read32(0xd8006a0);
	if(IsWiiU)
	{
		if( ConfigGetConfig(NIN_CFG_WIIU_WIDE) )
			write32(0xd8006a0, 0x30000004);
		else
			write32(0xd8006a0, 0x30000002);
		mask32(0xd8006a8, 0, 2);
	}
	while (1)
	{
		_ahbMemFlush(0);

		//Does interrupts again if needed
		if(TimerDiffTicks(InterruptTimer) > 15820) //about 120 times a second
		{
			sync_before_read((void*)INT_BASE, 0x80);
			if((read32(RSW_INT) & 2) || (read32(DI_INT) & 4) || 
				(read32(SI_INT) & 8) || (read32(EXI_INT) & 0x10))
				write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq
			InterruptTimer = read32(HW_TIMER);
		}
		#ifdef PATCHALL
		if (EXI_IRQ == true)
		{
			if(EXICheckTimer())
				EXIInterrupt();
		}
		#endif
		if (SI_IRQ != 0)
		{
			if ((TimerDiffTicks(PADTimer) > 7910) || (SI_IRQ & 0x2))	// about 240 times a second
			{
				SIInterrupt();
				PADTimer = read32(HW_TIMER);
			}
		}
		if(DI_IRQ == true)
		{
			if(DiscCheckAsync())
				DIInterrupt();
			else
				udelay(200); //let the driver load data
		}
		else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */
		{
			if(TimerDiffSeconds(Now) > 2) /* after 3 second earliest */
			{
				EXISaveCard();
				SaveCard = false;
			}
		}
		else if(UseUSB && TimerDiffSeconds(USBReadTimer) > 149) /* Read random sector every 2 mins 30 secs */
		{
			DIFinishAsync(); //if something is still running
			DI_CallbackMsg.result = -1;
			sync_after_write(&DI_CallbackMsg, 0x20);
			IOS_IoctlAsync( DI_Handle, 2, NULL, 0, NULL, 0, DI_MessageQueue, &DI_CallbackMsg );
			DIFinishAsync();
			USBReadTimer = read32(HW_TIMER);
		}
		udelay(10); //wait for other threads

		//Baten Kaitos save hax
		/*if( read32(0) == 0x474B4245 )
		{
			if( read32( 0x0073E640 ) == 0xFFFFFFFF )
			{
				write32( 0x0073E640, 0 );
			}
		}*/
		if( WaitForRealDisc == 1 )
		{
			if(RealDI_NewDisc())
			{
				DiscChangeTimer = read32(HW_TIMER);
				WaitForRealDisc = 2; //do another flush round, safety!
			}
		}
		else if( WaitForRealDisc == 2 )
		{
			if(TimerDiffSeconds(DiscChangeTimer))
			{
				//identify disc after flushing everything
				RealDI_Identify(false);
				//clear our fake regs again
				sync_before_read((void*)DI_BASE, 0x40);
				write32(DI_IMM, 0);
				write32(DI_COVER, 0);
				sync_after_write((void*)DI_BASE, 0x40);
				//mask and clear interrupts
				write32( DIP_STATUS, 0x54 );
				//disable cover irq which DIP enabled
				write32( DIP_COVER, 4 );
				DIInterrupt();
				WaitForRealDisc = 0;
			}
		}

		if ( DiscChangeIRQ == 1 )
		{
			DiscChangeTimer = read32(HW_TIMER);
			DiscChangeIRQ = 2;
		}
		else if ( DiscChangeIRQ == 2 )
		{
			if ( TimerDiffSeconds(DiscChangeTimer) > 2 )
			{
				DIInterrupt();
				DiscChangeIRQ = 0;
			}
		}
		_ahbMemFlush(1);
		DIUpdateRegisters();
		#ifdef PATCHALL
		EXIUpdateRegistersNEW();
		GCAMUpdateRegisters();
		BTUpdateRegisters();
		HIDUpdateRegisters(0);
		if(DisableSIPatch == 0) SIUpdateRegisters();
		#endif
		StreamUpdateRegisters();
		CheckOSReport();
		if(EXICheckCard())
		{
			Now = read32(HW_TIMER);
			SaveCard = true;
		}
		sync_before_read((void*)RESET_STATUS, 0x20);
		vu32 reset_status = read32(RESET_STATUS);
		if (reset_status == 0x1DEA)
		{
			write32(RESET_STATUS, 0);
			sync_after_write((void*)RESET_STATUS, 0x20);
			DIFinishAsync();
			break;
		}
		if (reset_status == 0x3DEA)
		{
			if (Reset == 0)
			{
				dbgprintf("Fake Reset IRQ\n");
				write32( RSW_INT, 0x2 ); // Reset irq
				sync_after_write( (void*)RSW_INT, 0x20 );
				write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq
				Reset = 1;
			}
		}
		else if (Reset == 1)
		{
			write32( RSW_INT, 0x10000 ); // send pressed
			sync_after_write( (void*)RSW_INT, 0x20 );
			ResetTimer = read32(HW_TIMER);
			Reset = 2;
		}
		/* The cleanup is not connected to the button press */
		if (Reset == 2)
		{
			if (TimerDiffTicks(ResetTimer) > 949219) //free after half a second
			{
				write32( RSW_INT, 0 ); // done, clear
				sync_after_write( (void*)RSW_INT, 0x20 );
				Reset = 0;
			}
		}
		if(reset_status == 0x4DEA)
			PatchGame();
		if(reset_status == 0x5DEA)
		{
			SetIPL();
			PatchGame();
		}
		if(reset_status == 0x6DEA)
		{
			SetIPL_TRI();
			write32(RESET_STATUS, 0);
			sync_after_write((void*)RESET_STATUS, 0x20);
		}
		if(read32(HW_GPIO_IN) & GPIO_POWER)
		{
			DIFinishAsync();
			#ifdef PATCHALL
			BTE_Shutdown();
			#endif
			Shutdown();
		}
		//sync_before_read( (void*)0x1860, 0x20 );
		//if( read32(0x1860) != 0xdeadbeef )
		//{
		//	if( read32(0x1860) != 0 )
		//	{
		//		dbgprintf(	(char*)(P2C(read32(0x1860))),
		//					(char*)(P2C(read32(0x1864))),
		//					(char*)(P2C(read32(0x1868))),
		//					(char*)(P2C(read32(0x186C))),
		//					(char*)(P2C(read32(0x1870))),
		//					(char*)(P2C(read32(0x1874)))
		//				);
		//	}
		//	write32(0x1860, 0xdeadbeef);
		//	sync_after_write( (void*)0x1860, 0x20 );
		//}
		cc_ahbMemFlush(1);
	}
	//if( UseHID )
		HIDClose();
	IOS_Close(DI_Handle); //close game
	thread_cancel(DI_Thread, 0);
	DIUnregister();

	/* reset time */
	while(1)
	{
		sync_before_read( (void*)RESET_STATUS, 0x20 );
		if(read32(RESET_STATUS) == 0x2DEA)
			break;
		wait_for_ppc(1);
	}

	if( ConfigGetConfig(NIN_CFG_LED) )
		clear32(HW_GPIO_OUT, GPIO_SLOT_LED);

	if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) )
		EXIShutdown();

	if (ConfigGetConfig(NIN_CFG_LOG))
		closeLog();

#ifdef PATCHALL
	BTE_Shutdown();
#endif

//unmount FAT device
	free(fatfs);
	fatfs = NULL;
	f_mount(NULL, fatDevName, 1);

	if(UseUSB)
		USBStorage_Shutdown();
	else
		SDHCShutdown();

//make sure we set that back to the original
	write32(HW_PPCSPEED, ori_ppcspeed);

	if(IsWiiU)
	{
		write32(0xd8006a0, ori_widesetting);
		mask32(0xd8006a8, 0, 2);
	}
DoIOSBoot:
	sync_before_read((void*)0x13003000, 0x420);
	IOSBoot((char*)0x13003020, 0, read32(0x13003000));
	return 0;
}
Пример #3
0
int _main( int argc, char *argv[] )
{
	//BSS is in DATA section so IOS doesnt touch it, we need to manually clear it
	//dbgprintf("memset32(%08x, 0, %08x)\n", &__bss_start, &__bss_end - &__bss_start);
	memset32(&__bss_start, 0, &__bss_end - &__bss_start);
	sync_after_write(&__bss_start, &__bss_end - &__bss_start);

	s32 ret = 0;
	u32 HID_Thread = 0, DI_Thread = 0;
	
	u8 MessageHeap[0x10];
	//u32 MessageQueue=0xFFFFFFFF;

	BootStatus(0, 0, 0);

	thread_set_priority( 0, 0x79 );	// do not remove this, this waits for FS to be ready!
	thread_set_priority( 0, 0x50 );
	thread_set_priority( 0, 0x79 );

	//MessageQueue = ES_Init( MessageHeap );
	ES_Init( MessageHeap );

	BootStatus(1, 0, 0);

#ifndef NINTENDONT_USB
	BootStatus(2, 0, 0);
	ret = SDHCInit();
	if(!ret)
	{
		dbgprintf("SD:SDHCInit() failed:%d\r\n", ret );
		BootStatusError(-2, ret);
		mdelay(2000);
		Shutdown();
	}
#endif
	BootStatus(3, 0, 0);
	fatfs = (FATFS*)malloca( sizeof(FATFS), 32 );

	s32 res = f_mount( 0, fatfs );
	if( res != FR_OK )
	{
		dbgprintf("ES:f_mount() failed:%d\r\n", res );
		BootStatusError(-3, res);
		mdelay(2000);
		Shutdown();
	}
	
	BootStatus(4, 0, 0);

	BootStatus(5, 0, 0);
	
	int MountFail = 0;
	s32 fres = -1;
	FIL fp;
	while(fres != FR_OK)
	{
		fres = f_open(&fp, "/bladie", FA_READ|FA_OPEN_EXISTING);
		switch(fres)
		{
			case FR_OK:
				f_close(&fp);
			case FR_NO_PATH:
			case FR_NO_FILE:
			{
				fres = FR_OK;
			} break;
			default:
			case FR_DISK_ERR:
			{
				f_mount(0, NULL);		//unmount drive todo: retry could never work
				MountFail++;
				if(MountFail == 10)
				{
					BootStatusError(-5, fres);
					mdelay(2000);
					Shutdown();
				}
				mdelay(5);
			} break;
		}
		if(STATUS_ERROR == -7) { // FS check timed out on PPC side
			dbgprintf("FS check timed out\r\n");
			mdelay(3000);
			Shutdown();
		}
	}
#ifndef NINTENDONT_USB
	s_size = 512;
	s_cnt = fatfs->n_fatent * fatfs->csize;
#endif

	BootStatus(6, s_size, s_cnt);

#ifdef NINTENDONT_USB
	s32 r = LoadModules(55);
	//dbgprintf("ES:ES_LoadModules(%d):%d\r\n", 55, r );
	if( r < 0 )
	{
		BootStatusError(-6, r);
		mdelay(2000);
		Shutdown();
	}
#endif

	BootStatus(7, s_size, s_cnt);
	ConfigInit();
	
	if (ConfigGetConfig(NIN_CFG_LOG))
		SDisInit = 1;  // Looks okay after threading fix
	dbgprintf("Game path: %s\r\n", ConfigGetGamePath());

	BootStatus(8, s_size, s_cnt);

	memset32((void*)0x13002800, 0, 0x30);
	sync_after_write((void*)0x13002800, 0x30);
	memset32((void*)0x13160000, 0, 0x20);
	sync_after_write((void*)0x13160000, 0x20);

	memset32((void*)0x13026500, 0, 0x100);
	sync_after_write((void*)0x13026500, 0x100);

	bool UseHID = ConfigGetConfig(NIN_CFG_HID);
	if( UseHID )
	{
		ret = HIDInit();
		if(ret < 0 )
		{
			dbgprintf("ES:HIDInit() failed\r\n" );
			BootStatusError(-8, ret);
			mdelay(2000);
			Shutdown();
		}
		write32(0x13003004, 0);
		sync_after_write((void*)0x13003004, 0x20);

		HID_Thread = thread_create(HID_Run, NULL, HID_ThreadStack, 0x400, 0x78, 1);
		thread_continue(HID_Thread);
	}
	BootStatus(9, s_size, s_cnt);

	DIRegister();
	DI_Thread = thread_create(DIReadThread, NULL, DI_ThreadStack, 0x400, 0x78, 1);
	thread_continue(DI_Thread);

	DIinit(true);

	BootStatus(10, s_size, s_cnt);

	GCAMInit();

	EXIInit();

	ret = Check_Cheats();
	if(ret < 0 )
	{
		dbgprintf("Check_Cheats failed\r\n" );
		BootStatusError(-10, ret);
		mdelay(4000);
		Shutdown();
	}
	
	BootStatus(11, s_size, s_cnt);

	bool PatchSI = !ConfigGetConfig(NIN_CFG_NATIVE_SI);
	if (PatchSI)
		SIInit();
	StreamInit();

	PatchInit();

//This bit seems to be different on japanese consoles
	u32 ori_ppcspeed = read32(HW_PPCSPEED);
	if((ConfigGetGameID() & 0xFF) == 'J')
		set32(HW_PPCSPEED, (1<<17));
	else
		clear32(HW_PPCSPEED, (1<<17));

	//write32( 0x1860, 0xdeadbeef );	// Clear OSReport area

//Tell PPC side we are ready!
	cc_ahbMemFlush(1);
	mdelay(1000);
	BootStatus(0xdeadbeef, s_size, s_cnt);

	u32 Now = read32(HW_TIMER);
	u32 PADTimer = Now;
	u32 DiscChangeTimer = Now;
	u32 ResetTimer = Now;
#ifdef NINTENDONT_USB
	u32 USBReadTimer = Now;
#endif
	u32 Reset = 0;
	bool SaveCard = false;
	if( ConfigGetConfig(NIN_CFG_LED) )
	{
		set32(HW_GPIO_ENABLE, GPIO_SLOT_LED);
		clear32(HW_GPIO_DIR, GPIO_SLOT_LED);
		clear32(HW_GPIO_OWNER, GPIO_SLOT_LED);
	}
	EnableAHBProt(-1); //disable AHBPROT
	write32(0xd8006a0, 0x30000004), mask32(0xd8006a8, 0, 2); //widescreen fix
	while (1)
	{
		_ahbMemFlush(0);

		//Check this.  Purpose is to send another interrupt if wasn't processed
		/*if (((read32(0x14) != 0) || (read32(0x13026514) != 0))
			&& (read32(HW_ARMIRQFLAG) & (1 << 30)) == 0)
		{
			write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq
		}*/
		#ifdef PATCHALL
		if (EXI_IRQ == true)
		{
			if(EXICheckTimer())
				EXIInterrupt();
		}
		#endif
		if ((PatchSI) && (SI_IRQ != 0))
		{
			if (((read32(HW_TIMER) - PADTimer) > 7910) || (SI_IRQ & 0x2))	// about 240 times a second
			{
				SIInterrupt();
				PADTimer = read32(HW_TIMER);
			}
		}
		if(DI_IRQ == true)
		{
			if(DI_CallbackMsg.result == 0)
				DIInterrupt();
		}
		else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */
		{
			if((read32(HW_TIMER) - Now) / 1898437 > 2) /* after 3 second earliest */
			{
				EXISaveCard();
				SaveCard = false;
			}
		}
		#ifdef NINTENDONT_USB
		else if((read32(HW_TIMER) - USBReadTimer) / 1898437 > 9) /* Read random sector after about 10 seconds */
		{
			DI_CallbackMsg.result = -1;
			sync_after_write(&DI_CallbackMsg, 0x20);
			IOS_IoctlAsync( DI_Handle, 2, NULL, 0, NULL, 0, DI_MessageQueue, &DI_CallbackMsg );
			while(DI_CallbackMsg.result)
			{
				udelay(10); //wait for other threads
				BTUpdateRegisters();
			}
			USBReadTimer = read32(HW_TIMER);
		}
		#endif
		udelay(10); //wait for other threads

		//Baten Kaitos save hax
		/*if( read32(0) == 0x474B4245 )
		{
			if( read32( 0x0073E640 ) == 0xFFFFFFFF )
			{
				write32( 0x0073E640, 0 );
			}
		}*/

		if ( DiscChangeIRQ == 1 )
		{
			DiscChangeTimer = read32(HW_TIMER);
			DiscChangeIRQ = 2;
		}
		else if ( DiscChangeIRQ == 2 )
		{
			if ( (read32(HW_TIMER) - DiscChangeTimer ) >  2 * 243000000 / 128)
			{
				//dbgprintf("DIP:IRQ mon!\r\n");
				set32( DI_SSTATUS, 0x3A );
				sync_after_write((void*)DI_SSTATUS, 4);
				DIInterrupt();
				DiscChangeIRQ = 0;
			}
		}
		_ahbMemFlush(1);
		DIUpdateRegisters();
		#ifdef PATCHALL
		EXIUpdateRegistersNEW();
		GCAMUpdateRegisters();
		BTUpdateRegisters();
		#endif
		StreamUpdateRegisters();
		CheckOSReport();
		if(EXICheckCard())
		{
			Now = read32(HW_TIMER);
			SaveCard = true;
		}
		if (PatchSI)
		{
			SIUpdateRegisters();
			if (read32(DIP_IMM) == 0x1DEA)
			{
				DIFinishAsync();
				break;
			}
			if (read32(DIP_IMM) == 0x3DEA)
			{
				if (Reset == 0)
				{
					dbgprintf("Fake Reset IRQ\n");
					write32(EXI2DATA, 0x2); // Reset irq
					write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq
					Reset = 1;
				}
			}
			else if (Reset == 1)
			{
				write32(EXI2DATA, 0x10000); // send pressed
				ResetTimer = read32(HW_TIMER);
				Reset = 2;
			}
			/* The cleanup is not connected to the button press */
			if (Reset == 2)
			{
				if ((read32(HW_TIMER) - ResetTimer) / 949219 > 0) //free after half a second
				{
					write32(EXI2DATA, 0); // done, clear
					write32(DIP_IMM, 0);
					Reset = 0;
				}
			}
		}
		if(read32(DIP_IMM) == 0x4DEA)
			PatchGame();
		CheckPatchPrs();
		if(read32(HW_GPIO_IN) & GPIO_POWER)
		{
			DIFinishAsync();
			#ifdef PATCHALL
			BTE_Shutdown();
			#endif
			Shutdown();
		}
		//sync_before_read( (void*)0x1860, 0x20 );
		//if( read32(0x1860) != 0xdeadbeef )
		//{
		//	if( read32(0x1860) != 0 )
		//	{
		//		dbgprintf(	(char*)(P2C(read32(0x1860))),
		//					(char*)(P2C(read32(0x1864))),
		//					(char*)(P2C(read32(0x1868))),
		//					(char*)(P2C(read32(0x186C))),
		//					(char*)(P2C(read32(0x1870))),
		//					(char*)(P2C(read32(0x1874)))
		//				);
		//	}
		//	write32(0x1860, 0xdeadbeef);
		//	sync_after_write( (void*)0x1860, 0x20 );
		//}
		cc_ahbMemFlush(1);
	}
	if( UseHID )
	{
		/* we're done reading inputs */
		thread_cancel(HID_Thread, 0);
	}

	IOS_Close(DI_Handle); //close game
	thread_cancel(DI_Thread, 0);
	DIUnregister();

	write32( DIP_IMM, 0 );
	/* reset time */
	while(1)
	{
		if(read32(DIP_IMM) == 0x2DEA)
			break;
		wait_for_ppc(1);
	}

	if( ConfigGetConfig(NIN_CFG_LED) )
		clear32(HW_GPIO_OUT, GPIO_SLOT_LED);

	if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) )
		EXIShutdown();

	if (ConfigGetConfig(NIN_CFG_LOG))
		closeLog();

#ifdef PATCHALL
	BTE_Shutdown();
#endif

//unmount FAT device
	f_mount(0, NULL);

#ifndef NINTENDONT_USB
	SDHCShutdown();
#endif

//make sure we set that back to the original
	write32(HW_PPCSPEED, ori_ppcspeed);

	IOSBoot((char*)0x13003020, 0, read32(0x13003000));
	return 0;
}
Пример #4
0
/* Start a stopped thread and stop it again immediately. The function replaces
 * the instruction at the PC to a breakpoint instruction, starts the thread and
 * waits for the thread to receive a SIGTRAP (or SIGILL) signal. After the
 * thread stops, the patched instruction is reverted.
 *
 * The function checks if the address pointed by the PC is actually inside an
 * executable memory segment. If it isn't, the function restarts the thread
 * without patching any instructions. The address pointed by the PC is
 * illegal, so the thread should receive a SIGSEGV signal in this case.
 *
 * The function must be called with all threads of the process stopped.
 * Moreover, the given process must still be alive (i.e. not a zombie).
 */
static bool fncall_restop(thread_t * thread) {

    int patch;
    int signo;
    struct pt_regs regs[2];
    
    /* Original instruction. */
    insn_t          insn;
    insn_kind_t     kind;
    address_t       address;
    
    assert(!thread->state.slavemode);
    thread->state.slavemode = true;
    
    info("Restopping thread %s...", str_thread(thread));
    
    /* Save current register values. */
    if (!thread_get_regs(thread, &regs[0]))
        goto fail;
        
    /* Get the current PC. */
    address = instruction_pointer(&regs[0]);
    
    patch = procfs_address_executable(thread, address);
    
    if (patch) {
        /* Read the original instruction. */
        kind = is_thumb_mode(&regs[0]) ? INSN_KIND_THUMB : INSN_KIND_ARM;
        if (!patch_read_insn_detect_kind(thread, address, &insn, &kind))
            goto fail;
            
        verbose("The PC register in thread %s points at address %p, "
                "which contains %s instruction '%s'. It will "
                "be temporary replaced by a breakpoint instruction. The thread "
                "will then be restarted. A SIGILL or SIGTRAP signal should be "
                "received immediately after thread restart.",
                str_thread(thread), (void *) address, insn_kind_str(kind), arm_disassemble(insn, kind));
                
        /* Patch instruction. */
        if (!patch_insn(thread, address, kind, get_breakpoint_insn(kind)))
            goto fail;
            
    } else {
        /* The address pointed by the PC is invalid. Running the thread should
         * cause a SIGSEGV. */
        verbose("The PC register in thread %s points at address %p, "
                "which is invalid (not inside a executable memory segment). "
                "It will be restarted without any patching. A SIGSEGV signal "
                "should be received immediately after thread restart.",
                str_thread(thread), (void *) address);
    }
    
    thread_continue(thread, 0);
    
    /* Wait until the program is stopped by a signal. */
    while (1) {
        thread_wait(thread, false);
        
        if (thread->state.dead)
            goto fail;
            
        if ((thread->state.signo == SIGSEGV) || (thread->state.signo == SIGTRAP) || (thread->state.signo == SIGBUS)) {
            break;
        }
        
        warning("Unexpected signal %s received during restopping of thread %s. The signal will be delivered.",
                str_signal(thread->state.signo), str_thread(thread));
                
        /* Deliver the signal. */
        thread_continue(thread, 0);
    }
    
    signo = thread->state.signo;
    thread->state.signo = 0;
    
    /* The process stopped, read new register values. */
    if (!thread_get_regs(thread, &regs[1]))
        goto fail;
        
    /* Warn about any abnormalities. */
    if (regs[1].ARM_pc != regs[0].ARM_pc) {
        warning("Unexpected change of PC register during restopping of %s.", str_thread(thread));
    }
    if (regs[1].ARM_lr != regs[0].ARM_lr) {
        warning("Unexpected change of LR register during restopping of %s.", str_thread(thread));
    }
    if (regs[1].ARM_sp != regs[0].ARM_sp) {
        warning("Unexpected change of SP register during restopping of %s.", str_thread(thread));
    }
    
    /* Restore old register values. */
    if (!thread_set_regs(thread, &regs[0]))
        goto fail;
        
    if (patch) {
        if ((signo != SIGILL) && (signo != SIGTRAP)) {
            warning("Thread %s was stopped by unexpected signal %s. Ignoring.",
                    str_thread(thread), str_signal(signo));
        }
        /* Revert original instruction */
        patch_insn(thread, address, kind, insn);
    } else {
        if ((signo != SIGSEGV)) {
            warning("%s was stopped by unexpected signal %s. Ignoring.",
                    str_thread(thread), str_signal(signo));
        }
    }
    
    info("Finished restop of %s.", str_thread(thread));
    
    thread->state.slavemode = false;
    if (!thread->state.dead)
        return true;
        
fail:
    assert(thread->state.dead);
    error("Thread %s died during restop operation.", str_thread(thread));
    return false;
}
Пример #5
0
//u32 Loopmode=0;
int _main( int argc, char *argv[] )
{
	s32 ret = 0;
	
	u8 MessageHeap[0x10];
	//u32 MessageQueue=0xFFFFFFFF;

	BootStatus(0, 0, 0);

	thread_set_priority( 0, 0x79 );	// do not remove this, this waits for FS to be ready!
	thread_set_priority( 0, 0x50 );
	thread_set_priority( 0, 0x79 );

	//MessageQueue = ES_Init( MessageHeap );
	ES_Init( MessageHeap );

	BootStatus(1, 0, 0);

#ifndef NINTENDONT_USB
	BootStatus(2, 0, 0);
	ret = SDHCInit();
	if(!ret)
	{
		dbgprintf("SD:SDHCInit() failed:%d\r\n", ret );
		BootStatusError(-2, ret);
		mdelay(2000);
		Shutdown();
	}
#endif
	BootStatus(3, 0, 0);
	fatfs = (FATFS*)malloca( sizeof(FATFS), 32 );

	s32 res = f_mount( 0, fatfs );
	if( res != FR_OK )
	{
		dbgprintf("ES:f_mount() failed:%d\r\n", res );
		BootStatusError(-3, res);
		mdelay(2000);
		Shutdown();
	}
	
	BootStatus(4, 0, 0);

	BootStatus(5, 0, 0);
	
	int MountFail = 0;
	s32 fres = -1; 
	while(fres != FR_OK)
	{
		fres = f_open(&GameFile, "/bladie", FA_READ|FA_OPEN_EXISTING);
		switch(fres)
		{
			case FR_OK:
				f_close(&GameFile);
			case FR_NO_PATH:
			case FR_NO_FILE:
			{
				fres = FR_OK;
			} break;
			default:
			case FR_DISK_ERR:
			{
				f_mount(0, 0);		//unmount drive todo: retry could never work
				MountFail++;
				if(MountFail == 10)
				{
					BootStatusError(-5, fres);
					mdelay(2000);
					Shutdown();
				}
				mdelay(5);
			} break;
		}
	}

#ifdef NINTENDONT_USB
	BootStatus(6, s_size, s_cnt);
	s32 r = LoadModules(55);
	//dbgprintf("ES:ES_LoadModules(%d):%d\r\n", 55, r );
	if( r < 0 )
	{
		BootStatusError(-6, r);
		mdelay(2000);
		Shutdown();
	}
#endif

	BootStatus(7, s_size, s_cnt);
	ConfigInit();
	
	BootStatus(8, s_size, s_cnt);

	SDisInit = 1;

	memset32((void*)0x13002800, 0, 0x30);
	sync_after_write((void*)0x13002800, 0x30);
	u32 HID_Thread = 0;
	bool UseHID = ConfigGetConfig(NIN_CFG_HID);
	if( UseHID )
	{
		ret = HIDInit();
		if(ret < 0 )
		{
			dbgprintf("ES:HIDInit() failed\r\n" );
			BootStatusError(-8, ret);
			mdelay(2000);
			Shutdown();
		}
		write32(0x13003004, 0);
		sync_after_write((void*)0x13003004, 0x20);

		memset32((void*)0x13003420, 0, 0x1BE0);
		sync_after_write((void*)0x13003420, 0x1BE0);
		HID_Thread = thread_create(HID_Run, NULL, (u32*)0x13003420, 0x1BE0, 0x78, 1);
		thread_continue(HID_Thread);
	}
	BootStatus(9, s_size, s_cnt);

	DIinit();
	BootStatus(10, s_size, s_cnt);

	EXIInit();
	BootStatus(11, s_size, s_cnt);

	SIInit();

//fixes issues in some japanese games
	if((ConfigGetGameID() & 0xFF) == 'J')
		write32(HW_PPCSPEED, 0x2A9E0);

//Tell PPC side we are ready!
	cc_ahbMemFlush(1);
	mdelay(1000);
	BootStatus(0xdeadbeef, s_size, s_cnt);
/*
	write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) );
	write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) );

	set32( HW_PPCIRQMASK, (1<<31) );
	set32( HW_IPC_PPCCTRL, 0x30 );
*/
	u32 Now = read32(HW_TIMER);
	u32 PADTimer = Now;

	bool SaveCard = false;
	if( ConfigGetConfig(NIN_CFG_LED) )
	{
		set32(HW_GPIO_ENABLE, GPIO_SLOT_LED);
		clear32(HW_GPIO_DIR, GPIO_SLOT_LED);
		clear32(HW_GPIO_OWNER, GPIO_SLOT_LED);
	}
	write32(0xd8006a0, 0x30000004), mask32(0xd8006a8, 0, 2);
	while (1)
	{
		_ahbMemFlush(0);

		if(EXI_IRQ == true)
		{
			if(EXICheckTimer())
				EXIInterrupt();
		}
		if(SI_IRQ == true)
		{
			if((read32(HW_TIMER) - PADTimer) >= 65000)	// about 29 times a second
			{
				SIInterrupt();
				PADTimer = read32(HW_TIMER);
			}
		}
		if(DI_IRQ == true)
		{
			if(DI_Args->Buffer == 0xdeadbeef)
				DIInterrupt();
		}
		else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */
		{
			if((read32(HW_TIMER) - Now) / 1898437 > 2) /* after 3 second earliest */
			{
				EXISaveCard();
				SaveCard = false;
			}
		}
		udelay(10); //wait for other threads

		//Baten Kaitos save hax
		if( read32(0) == 0x474B4245 )
		{
			if( read32( 0x0073E640 ) == 0xFFFFFFFF )
			{
				write32( 0x0073E640, 0 );
			}
		}

		if( Streaming )
		{
			if( (read32(HW_TIMER) * 19 / 10) - StreamTimer >= 5000000 )
			{
			//	dbgprintf(".");
				StreamOffset += 64*1024;

				if( StreamOffset >= StreamSize )
				{
					StreamOffset = StreamSize;
					Streaming = 0;
				}
				StreamTimer = read32(HW_TIMER) * 19 / 10;
			}
		}

		if( DiscChangeIRQ )
		{
			if( read32(HW_TIMER) * 128 / 243000000 > 2 )
			{
				//dbgprintf("DIP:IRQ mon!\r\n");
				set32( DI_SSTATUS, 0x3A );
				sync_after_write((void*)DI_SSTATUS, 4);
				DIInterrupt();
				DiscChangeIRQ = 0;
			}
		}
		_ahbMemFlush(1);
		DIUpdateRegisters();
		EXIUpdateRegistersNEW();
		SIUpdateRegisters();
		if(EXICheckCard())
		{
			Now = read32(HW_TIMER);
			SaveCard = true;
		}
		if(read32(DI_SCONFIG) == 0x1DEA)
		{
			while(DI_Args->Buffer != 0xdeadbeef)
				udelay(100);
			break;
		}
		cc_ahbMemFlush(1);
	}
	if( UseHID )
	{
		/* we're done reading inputs */
		thread_cancel(HID_Thread, 0);
	}
	thread_cancel(DI_Thread, 0);

	write32( DI_SCONFIG, 0 );
	sync_after_write( (void*)DI_SCONFIG, 4 );
	/* reset time */
	while(1)
	{
		_ahbMemFlush(0);
		sync_before_read( (void*)DI_SCONFIG, 4 );
		if(read32(DI_SCONFIG) == 0x2DEA)
			break;
		wait_for_ppc(1);
		cc_ahbMemFlush(1);
	}

	if( ConfigGetConfig(NIN_CFG_LED) )
		clear32(HW_GPIO_OUT, GPIO_SLOT_LED);

	if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) )
		EXIShutdown();
	IOSBoot((char*)0x13003020, 0, read32(0x13003000));
	return 0;
}