Exemple #1
0
int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec)
{
	u32 i;

	memset(&ipc, 0, sizeof ipc);

	for (i = 0; i < in_count + out_count; i++)
		if (vec[i].data) {
			sync_after_write(vec[i].data, vec[i].len);
			vec[i].data = (void *)virt_to_phys(vec[i].data);
		}

	sync_after_write(vec, (in_count + out_count) * sizeof *vec);

	ipc.cmd = 7;
	ipc.fd = fd;
	ipc.arg[0] = n;
	ipc.arg[1] = in_count;
	ipc.arg[2] = out_count;
	ipc.arg[3] = virt_to_phys(vec);

	ipc_send_request();
	ipc_recv_reply();

	for (i = in_count; i < in_count + out_count; i++)
		if (vec[i].data) {
			vec[i].data = phys_to_virt((u32)vec[i].data);
			sync_before_read(vec[i].data, vec[i].len);
		}

	return ipc.result;
}
Exemple #2
0
int ios_ioctl(int fd, u32 n, const void *in, u32 inlen, void *out, u32 outlen)
{
	memset(&ipc, 0, sizeof ipc);

	if (in)
		sync_after_write(in, inlen);
	if (out)
		sync_after_write(out, outlen);

	ipc.cmd = 6;
	ipc.fd = fd;
	ipc.arg[0] = n;
	ipc.arg[1] = virt_to_phys(in);
	ipc.arg[2] = inlen;
	ipc.arg[3] = virt_to_phys(out);
	ipc.arg[4] = outlen;

	ipc_send_request();
	ipc_recv_reply();

	if (out)
		sync_before_read(out, outlen);

	return ipc.result;
}
Exemple #3
0
void ParseTGC(char *Data, u32 Length, u32 Offset)
{
	if(TGCInfo->isTGC == 0)
		return;

	if(Offset == 0x420) /* update internal gcm header with the tgc header */
	{
		*(vu32*)(Data+0x00) = TGCInfo->doloffset;
		*(vu32*)(Data+0x04) = TGCInfo->fstoffset;
		*(vu32*)(Data+0x08) = TGCInfo->fstsize;
		*(vu32*)(Data+0x0C) = TGCInfo->fstsize;
		*(vu32*)(Data+0x34) = TGCInfo->userpos;
		*(vu32*)(Data+0x38) = 0x57058000L - (TGCInfo->userpos);
		sync_after_write(Data, Length);
	}
	else if(Offset == TGCInfo->fstoffset) /* update internal gcm fst with correct tgc positions */
	{
		char *FSTable = Data;
		u32 FSTEnt = *(u32*)(FSTable+0x08);
		FST *fst = (FST *)(FSTable);
		u32 i;
		for(i = 1; i < FSTEnt; ++i)
		{
			if(fst[i].Type == 0) /* update file offset */
				fst[i].FileOffset -= TGCInfo->fstupdate;
		}
		sync_after_write(Data, Length);
	}
}
Exemple #4
0
void nand_write(u32 pageno, void *data, void *ecc)
{
	if (data)
		sync_after_write(data, 0x800);
	if (ecc)
		sync_after_write(ecc, 0x40);
	ipc_exchange(IPC_NAND_WRITE, 3, pageno,
		(!data ? (u32)-1 : virt_to_phys(data)),
		(!ecc ? (u32)-1 : virt_to_phys(ecc)));
}
Exemple #5
0
int sd_write(u32 start_block, u32 blk_cnt, const void *buffer)
{
	int retval;
	sync_after_write(buffer, blk_cnt * 512);
	retval = ipc_exchange(IPC_SDMMC_WRITE, 3, start_block, blk_cnt, virt_to_phys(buffer))->args[0];

	return retval;
}
Exemple #6
0
int ipc_powerpc_boot(const void *addr, u32 len)
{
	ipc_request *req;

	sync_after_write(addr, len);
	req =  ipc_exchange(IPC_PPC_BOOT, 3, 0, virt_to_phys(addr), len);
	return req->args[0];
}
Exemple #7
0
void
_main(void)
{
#if DEBUG
	usbgecko_init();
	usbgecko_printf("_main()\n");
#endif

	ios_reload();
#if DEBUG
	usbgecko_printf("ios_reload()\n");
#endif

	sync_before_read((void*)0x93010010, 0x1800);
	_memcpy((void*)0x80001800, (void*)0x93010010, 0x1800);
	sync_after_write((void*)0x80001800, 0x1800);
	if(*(vu32*)0xC0001804 == 0x53545542 && *(vu32*)0xC0001808 == 0x48415858) //stubhaxx
	{
		__asm(
			"sync ; isync\n"
			"lis %r3, 0x8000\n"
			"ori %r3, %r3, 0x1800\n"
			"mtlr %r3\n"
			"blr\n"
		);
	}
#if DEBUG
	usbgecko_printf("no loader stub, using internal\n");
#endif

	ios_cleanup();
#if DEBUG
	usbgecko_printf("ios_cleanup()\n");
#endif
	es_init();
#if DEBUG
	usbgecko_printf("es_init()\n");
#endif
	u64 ios_titleid = TITLE_ID(1, 35); //just to get away from the kernel
	es_launchtitle(ios_titleid);
#if DEBUG
	usbgecko_printf("es_launchtitle()\n");
#endif
	es_init();
#if DEBUG
	usbgecko_printf("es_init()\n");
#endif
	es_launchtitle(HBC_LULZ);
	es_launchtitle(HBC_108);
	es_launchtitle(HBC_JODI);
	es_launchtitle(HBC_HAXX);
	es_launchtitle(SYSTEM_MENU);
#if DEBUG
	usbgecko_printf("es_launchtitle()\n");
#endif

	while (1);
}
Exemple #8
0
static void ipc_send_request(void)
{
	sync_after_write(&ipc, 0x40);

	ipc_write(0, virt_to_phys(&ipc));
	ipc_bell(1);

	ipc_wait_ack();

	ipc_bell(2);
	ipc_irq_ack();
}
Exemple #9
0
void TRIReset()
{
	//Reset GCAM status
	GCAMInit();
	//F-Zero AX uses Clean CARD after 150 uses
	if(TRIGame == TRI_AX && TRI_BackupAvailable == 1)
	{
		//if we dont set it to 150 it'll beep a lot
		sync_before_read(OUR_SETTINGS_LOC, 0x20);
		W16((u32)OUR_SETTINGS_LOC+0x16,150);
		sync_after_write(OUR_SETTINGS_LOC, 0x20);
	}
}
Exemple #10
0
static s32 BTHandleData(void *arg,void *buffer,u16 len)
{
	sync_before_read(arg, sizeof(struct BTPadStat));
	struct BTPadStat *stat = (struct BTPadStat*)arg;
	u32 chan = stat->channel;

	if(*(u8*)buffer == 0x3D)	//21 expansion bytes report
	{
		if(stat->transferstate == TRANSFER_CALIBRATE)
		{
			stat->xAxisLmid = bswap16(R16((u32)(((u8*)buffer)+1)));
			stat->xAxisRmid = bswap16(R16((u32)(((u8*)buffer)+3)));
			stat->yAxisLmid = bswap16(R16((u32)(((u8*)buffer)+5)));
			stat->yAxisRmid = bswap16(R16((u32)(((u8*)buffer)+7)));
			stat->transferstate = TRANSFER_DONE;
			sync_after_write(arg, sizeof(struct BTPadStat));
			sync_before_read(arg, sizeof(struct BTPadStat));
		}
		if(chan == CHAN_NOT_SET)
			return ERR_OK;
		sync_before_read(&BTPad[chan], sizeof(struct BTPadCont));
		BTPad[chan].xAxisL = ((bswap16(R16((u32)(((u8*)buffer)+1))) - stat->xAxisLmid) *3) >>5;
		BTPad[chan].xAxisR = ((bswap16(R16((u32)(((u8*)buffer)+3))) - stat->xAxisRmid) *3) >>5;
		BTPad[chan].yAxisL = ((bswap16(R16((u32)(((u8*)buffer)+5))) - stat->yAxisLmid) *3) >>5;
		BTPad[chan].yAxisR = ((bswap16(R16((u32)(((u8*)buffer)+7))) - stat->yAxisRmid) *3) >>5;
		u32 prevButton = BTPad[chan].button;
		BTPad[chan].button = ~(R16((u32)(((u8*)buffer)+9)));
		if((!(prevButton & BT_BUTTON_SELECT)) && BTPad[chan].button & BT_BUTTON_SELECT)
		{
			//dbgprintf("Using %s control scheme\n", (stat->controller & C_SWAP) ? "orginal" : "swapped");
			stat->controller = (stat->controller & C_SWAP) ? (stat->controller & ~C_SWAP) : (stat->controller | C_SWAP);
			sync_after_write(arg, sizeof(struct BTPadStat));
			sync_before_read(arg, sizeof(struct BTPadStat));
		}
		BTPad[chan].used = stat->controller;
		sync_after_write(&BTPad[chan], sizeof(struct BTPadCont));
	}
	else if(*(u8*)buffer == 0x34)	//core buttons with 19 exptension bytes report
Exemple #11
0
static void releasse_old_stm_callback(void)
{
	*((u32 *)0x80000018) = 0x00000014;
	sync_after_write((void*)0x80000014, 8);

	int fd = ios_open("/dev/stm/immediate",0);
	if (fd < 0) {
		return;
	}

	//int err = ios_ioctl(fd, 0x3002, 0, 0, 0, 0);

	ios_close(fd);
}
Exemple #12
0
int ios_open(const char *filename, u32 mode)
{
	sync_after_write(filename, strlen(filename) + 1);
	memset(&ipc, 0, sizeof ipc);

	ipc.cmd = 1;
	ipc.fd = 0;
	ipc.arg[0] = virt_to_phys(filename);
	ipc.arg[1] = mode;

	ipc_send_request();
	ipc_recv_reply();

	return ipc.result;
}
Exemple #13
0
void
__init_syscall()
{
	u8* sc_vector = SYSCALL_VECTOR;
	u32 bytes = (u32)DCFlashInvalidate - (u32)__temp_abe;
	u8* from = (u8*)__temp_abe;
	for ( ; bytes != 0 ; --bytes )
	{
		*sc_vector = *from;
		sc_vector++;
		from++;
	}

	sync_after_write(SYSCALL_VECTOR, 0x100);
	ICInvalidateRange(SYSCALL_VECTOR, 0x100);
}
Exemple #14
0
void ConfigInit( void )
{
	FIL cfg;
	u32 read;

	dbgprintf("CFGInit()\r\n");
	ConfigSyncBeforeRead();
	if (ncfg->Magicbytes != 0x01070CF6)
	{
		dbgprintf("Cfg not in memory, trying file\r\n");
		if (f_open_char(&cfg, "/nincfg.bin", FA_OPEN_EXISTING | FA_READ) != FR_OK)
		{
			dbgprintf("CFG:Failed to open config\r\n");
			Shutdown();
		}

		f_read( &cfg, ncfg, sizeof(NIN_CFG), &read );
		sync_after_write(ncfg, sizeof(NIN_CFG));
		f_close( &cfg );

		if( read != sizeof(NIN_CFG) )
		{
			dbgprintf("CFG:Failed to read config\r\n");
			Shutdown();
		}
		ConfigSyncBeforeRead();
	}

	if( IsWiiU() )
	{
		//ncfg->Config |= NIN_CFG_HID;
		ncfg->MaxPads = 0;

		// Disable debugging and the drive access LED.
		ncfg->Config &= ~(NIN_CFG_DEBUGGER | NIN_CFG_DEBUGWAIT | NIN_CFG_LED);
	}

	//if( (read32(0) >> 8) == 0x47504F )	// PSO 1&2 disable cheats/debugging
	//{
	//	ncfg->Config &= ~(NIN_CFG_CHEATS|NIN_CFG_DEBUGGER|NIN_CFG_DEBUGWAIT);
	//}
}
Exemple #15
0
void GCAMInit( void )
{
	if(BufsAllocated == 0)
	{
		Bufo= (char*)malloca( 0x80, 32 );
		Bufi= (char*)malloca( 0x80, 32 );
		Buf = (char*)malloca( 0x80, 32 );
		res = (u8*)  malloca( 0x80, 32 );

		CARDMemory = (u8*)malloca( 0xD0, 32 );
		CARDReadPacket = (u8*)malloca( 0xDB, 32 );
		CARDBuffer = (u8*)malloca( 0x100, 32 );
		BufsAllocated = 1;
	}
	memset32( Bufo, 0, 0x80 );
	memset32( Bufi, 0, 0x80 );
	memset32( Buf,  0, 0x80 );
	memset32( res,  0, 0x80 );

	memset32( CARDMemory, 0, 0xD0 );
	memset32( CARDReadPacket, 0, 0xDB );
	memset32( CARDBuffer, 0, 0x100 );

	memset32( (void*)GCAM_BASE, 0xdeadbeef, 0x40 );
	sync_after_write( (void*)GCAM_BASE, 0x40 );

	CARDMemorySize = 0;
	CARDIsInserted = 0;
	CARDCommand = 0;
	CARDClean = 0;
	CARDWriteLength = 0;
	CARDWrote = 0;
	CARDReadLength = 0;
	CARDRead = 0;
	CARDBit = 0;
	CARDStateCallCount = 0;
	CARDOffset = 0;
	FirstCMD = 0;
}
Exemple #16
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;
}
Exemple #17
0
void aes_decrypt(u8 *src, u8 *dst, u32 blocks, u8 keep_iv)
{
	sync_after_write(src, (blocks+1)*16);
	ipc_exchange(IPC_AES_DECRYPT, 4, virt_to_phys(src), virt_to_phys(dst), blocks, keep_iv);
	sync_before_read(dst, (blocks+1)*16);
}
Exemple #18
0
void GCAMCARDCommand( char *DataIn, char *DataOut )
{
	if( DataIn[DataPos] == 1 && DataIn[DataPos+1] == 0x05 )
	{
	//	dbgprintf("CARDGetReply(%02X)\n", CARDCommand );

		if( CARDReadLength )
		{
			res[resp++] = 0x32;

			u32 ReadLength = CARDReadLength - CARDRead;
			if( TRIGame == TRI_AX )
			{
				if( ReadLength > 0x2F )
					ReadLength = 0x2F;
			}
			res[resp++] = ReadLength;	// 0x2F (max size per packet)

			memcpy( res+resp, CARDReadPacket+CARDRead, ReadLength );

			resp			+= ReadLength;
			CARDRead	+= ReadLength;
							
		//	dbgprintf("CARDRead: %u/%u\n", CARDRead, CARDReadLength );									

			if( CARDRead >= CARDReadLength )
				CARDReadLength = 0;

		//	hexdump( res, 0x80 );

			DataPos += DataIn[DataPos] + 1;

			return;
		}

		res[resp++] = 0x32;
		u32 CMDLenO	= resp;
		res[resp++] = 0x00;	// len
							
		res[resp++] = 0x02; //
		u32 ChkStart = resp;

		res[resp++] = 0x00;	// 0x00		 len
		switch(CARDCommand)
		{
			case CARD_INIT:
			{
				res[resp++] = 0x10;	// 0x01
				res[resp++] = 0x00;	// 0x02
				res[resp++] = 0x30;	// 0x03
			} break;
			case CARD_IS_PRESENT:
			{
				res[resp++] = 0x40;	// 0x01
				res[resp++] = 0x22;	// 0x02
				res[resp++] = 0x30;	// 0x03
			} break;
			case CARD_GET_CARD_STATE:
			{
				res[resp++] = 0x20;	// 0x01
				res[resp++] = 0x20|CARDBit;	// 0x02
				/*
					bit 0: PLease take your card
					bit 1: endless waiting casues UNK_E to be called
				*/
				res[resp++] = 0x00;	// 0x03
			} break;
			case CARD_7A:
			{
				res[resp++] = 0x7A;	// 0x01
				res[resp++] = 0x00;	// 0x02
				res[resp++] = 0x00;	// 0x03
			} break;
			case CARD_78:
			{
				res[resp++] = 0x78;	// 0x01
				res[resp++] = 0x00;	// 0x02
				res[resp++] = 0x00;	// 0x03
			} break;
			case CARD_WRITE_INFO:
			{
				res[resp++] = 0x7C;	// 0x01
				res[resp++] = 0x02;	// 0x02
				res[resp++] = 0x00;	// 0x03
			} break;
			case CARD_D0:
			{
				res[resp++] = 0xD0;	// 0x01
				res[resp++] = 0x00;	// 0x02
				res[resp++] = 0x00;	// 0x03
			} break;
			case CARD_80:
			{
				res[resp++] = 0x80;	// 0x01

				if( TRIGame == TRI_AX )
					res[resp++] = 0x01;	// 0x02
				else
					res[resp++] = 0x31;	// 0x02

				res[resp++] = 0x30;	// 0x03
			} break;
			case CARD_CLEAN_CARD:
			{
				res[resp++] = 0xA0;	// 0x01
				res[resp++] = 0x02;	// 0x02
				res[resp++] = 0x00;	// 0x03
			} break;
			case CARD_LOAD_CARD:
			{
				res[resp++] = 0xB0;	// 0x01
				res[resp++] = 0x02;	// 0x02
				res[resp++] = 0x30;	// 0x03
			} break;
			case CARD_WRITE:
			{
				res[resp++] = 0x53;	// 0x01
				res[resp++] = 0x02;	// 0x02
				res[resp++] = 0x00;	// 0x03
			} break;
			case CARD_READ:
			{
				res[resp++] = 0x33;	// 0x01
				res[resp++] = 0x02;	// 0x02
				res[resp++] = 0x53;	// 0x03
			} break;									
		}

		res[resp++] = 0x30;	// 0x04
		res[resp++] = 0x00;	// 0x05

		res[resp++] = 0x03;	// 0x06

		res[ChkStart] = resp-ChkStart;	// 0x00 len

		u32 i;
		res[resp] = 0;		// 0x07
		for( i=0; i < res[ChkStart]; ++i )
			res[resp] ^= res[ChkStart+i];
							
		resp++;	

		res[CMDLenO] = res[ChkStart] + 2;

	}
	else
	{

		memcpy( CARDBuffer + CARDOffset, DataIn+DataPos+1, DataIn[DataPos] );
		CARDOffset += DataIn[DataPos];

		//Check if we got complete CMD

		if( CARDBuffer[0] == 0x02 )
		{
			if( CARDBuffer[1] == CARDOffset - 2 )
			{
				if( CARDBuffer[CARDOffset-2] == 0x03 )
				{
					u32 cmd = CARDBuffer[2] << 24;
						cmd|= CARDBuffer[3] << 16;
						cmd|= CARDBuffer[4] <<  8;
						cmd|= CARDBuffer[5] <<  0;

					switch(cmd)
					{
						default:
						{
						//	dbgprintf("CARD:Unhandled cmd!\n");
						//	dbgprintf("CARD:[%08X]\n", cmd );
						//	hexdump( CARDBuffer, CARDOffset );
						} break;
						case 0x10000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDInit()\n");
		#endif
							CARDCommand = CARD_INIT;

							CARDWriteLength		= 0;
							CARDBit				= 0;
							CARDMemorySize			= 0;
							CARDStateCallCount	= 0;

						} break;
						case 0x20000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDGetState(%02X)\n", CARDBit );
		#endif
							CARDCommand = CARD_GET_CARD_STATE;

							if( TRIGame == TRI_AX && CARDMemorySize )
							{
								CARDStateCallCount++;
								if( CARDStateCallCount > 10 )
								{
									if( CARDBit & 2 )
										CARDBit &= ~2;
									else
										CARDBit |= 2;

									CARDStateCallCount = 0;
								}
							}

							if( CARDClean == 1 )
							{
								CARDClean = 2;
							} else if( CARDClean == 2 )
							{
								DIFinishAsync(); //DONT ever try todo file i/o async
								FIL fi;
								if( f_open_char( &fi, GCAMGetCARDName(), FA_READ|FA_OPEN_EXISTING ) == FR_OK )
								{
									if( fi.fsize > 0 )
									{
										CARDMemorySize = fi.fsize;
										if( TRIGame == TRI_AX )
											CARDBit = 2;
										else
											CARDBit = 1;
									}
									f_close(&fi);
								}
								CARDClean = 0;
							}
						} break;
						case 0x40000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDIsPresent()\n");
		#endif
							CARDCommand = CARD_IS_PRESENT;
						} break;
						case 0x7A000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDUnknown7A()\n");
		#endif
							CARDCommand = CARD_7A;
							//hexdump( CARDBuffer+2, CARDOffset-2 );
						} break;
						case 0xB0000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDLoadCard()\n");
		#endif
							CARDCommand = CARD_LOAD_CARD;
						} break;
						case 0xA0000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDIsCleanCard?()\n");
		#endif
							CARDCommand = CARD_CLEAN_CARD;
							CARDClean = 1;
						} break;
						case 0x33000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDRead()\n");
		#endif
							CARDCommand		= CARD_READ;

							//Prepare read packet
							memset( CARDReadPacket, 0, 0xDB );
							u32 POff=0;

							DIFinishAsync(); //DONT ever try todo file i/o async
							FIL cf;
							if( f_open_char( &cf, GCAMGetCARDName(), FA_READ|FA_OPEN_EXISTING ) == FR_OK )
							{
								if( CARDMemorySize == 0 )
									CARDMemorySize = cf.fsize;

								u32 read;
								f_read( &cf, CARDMemory, CARDMemorySize, &read );
								f_close( &cf );
								sync_after_write(CARDMemory, CARDMemorySize);
								CARDIsInserted = 1;
							}

							CARDReadPacket[POff++] = 0x02;	// SUB CMD
							CARDReadPacket[POff++] = 0x00;	// SUB CMDLen

							CARDReadPacket[POff++] = 0x33;	// CARD CMD

							if( CARDIsInserted )
							{
								CARDReadPacket[POff++] = '1';	// CARD Status
							} else {
								CARDReadPacket[POff++] = '0';	// CARD Status
							}

							CARDReadPacket[POff++] = '0';		// 
							CARDReadPacket[POff++] = '0';		// 

							//Data reply
							sync_before_read(CARDMemory, CARDMemorySize);
							memcpy( CARDReadPacket + POff, CARDMemory, CARDMemorySize );
							POff += CARDMemorySize;

							CARDReadPacket[POff++] = 0x03;

							CARDReadPacket[1] = POff-1;	// SUB CMDLen

							u32 i;
							for( i=0; i < POff-1; ++i )
								CARDReadPacket[POff] ^= CARDReadPacket[1+i];

							POff++;

						//	hexdump( CARDReadPacket, POff );

							CARDReadLength	= POff;
							CARDRead	= 0;
						} break;
						case 0x53000000:
						{
							CARDCommand		= CARD_WRITE;

							CARDMemorySize		= CARDBuffer[1] - 9;

							memcpy( CARDMemory, CARDBuffer+9, CARDMemorySize );
		#ifdef DEBUG_CARD
							dbgprintf("CARDWrite: %u\n", CARDMemorySize );
		#endif
							u32 CARDIsValid;
							switch(TRIGame)
							{
								case TRI_GP1:
								case TRI_GP2:
									CARDIsValid = (memcmp(CARDMemory, "MKA", 3) == 0);
									break;
								case TRI_AX:
									CARDIsValid = (memcmp(CARDMemory+0x8A, "SEGABGG", 7) == 0);
									break;
								default:
									CARDIsValid = 0;
									break;
							}
							if(CARDIsValid)
							{
								DIFinishAsync(); //DONT ever try todo file i/o async
								FIL cf;
								if( f_open_char( &cf, GCAMGetCARDName(), FA_WRITE|FA_CREATE_ALWAYS ) == FR_OK )
								{
									u32 wrote;
									f_write( &cf, CARDMemory, CARDMemorySize, &wrote );
									f_close( &cf );
								}
							}
							CARDBit = 2;
							sync_after_write(CARDMemory, CARDMemorySize);
							CARDStateCallCount = 0;
						} break;
						case 0x78000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDUnknown78()\n");
		#endif
							CARDCommand	= CARD_78;
						} break;
						case 0x7C000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDWriteCardInfo()\n");
		#endif
							CARDCommand	= CARD_WRITE_INFO;
						//	hexdump( CARDBuffer, CARDOffset );
						} break;
						case 0x7D000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDPrint?()\n");
		#endif
							CARDCommand	= CARD_7D;
						} break;
						case 0x80000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDUnknown80()\n");
		#endif
							CARDCommand	= CARD_80;

							if( TRIGame != TRI_AX )
								CARDBit = 0;
						} break;
						case 0xD0000000:
						{
		#ifdef DEBUG_CARD
							dbgprintf("CARDUnknownD0()\n");
		#endif
							CARDCommand	= CARD_D0;

							if( TRIGame != TRI_AX )
								CARDBit = 0;
						} break;
					}

				//	hexdump( CARDBuffer, CARDOffset );

					CARDOffset = 0;
				}
			}
		}

		res[resp++] = 0x32;
		res[resp++] = 0x01;	// len
		res[resp++] = 0x06;	// OK

	}
}
Exemple #19
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;
}
Exemple #20
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;
}
Exemple #21
0
void GCAMUpdateRegisters( void )
{
	u32 i;

	u32 *GInterface	 = (u32*)(GCAM_BASE);
	u32 *GInterfaceS = (u32*)(GCAM_SHADOW);
	
	sync_before_read( (void*)GCAM_BASE, 0x40 );

	if( read32(GCAM_CONTROL) != 0xdeadbeef )
	{
		if( read32( GCAM_CONTROL ) & (~3) )
		{
			write32( GCAM_CONTROL, 0xdeadbeef );
			sync_after_write( (void*)GCAM_BASE, 0x40 );
			return;
		}

		/*write32( GCAM_SCONTROL, read32(GCAM_CONTROL) & 3 );
		clear32( GCAM_SSTATUS, 0x14 );

		write32( GCAM_CONTROL, 0xdeadbeef );
		write32( GCAM_RETURN, 0xdeadbeef );
		write32( GCAM_STATUS, 0xdeadbeef );

		sync_after_write( (void*)GCAM_BASE, 0x40 );*/
		
		for( i=0; i < 5; ++i )
		{
			if( GInterface[i] != 0xdeadbeef )
			{
				GInterfaceS[i] = GInterface[i];
				GInterface[i]  = 0xdeadbeef;
			}
		}

		switch( read32(GCAM_SCMD) >> 24 )
		{
			case 0x00:
			{
				//dbgprintf("CARD:Warning unknown command!\n");
			} break;
			case 0x50:
			{
				char	*datain		= (char*)P2C( read32(GCAM_SCMD_1) );
				u32		lenin			= read32(GCAM_SCMD_2);

				char	*dataout	= (char*)P2C( read32(GCAM_SCMD_3) );
				u32		lenout		= read32(GCAM_SCMD_4);

#ifdef DEBUG_GCAM
				dbgprintf("SI:Transfer( %p, %u, %p, %u )\n", datain, lenin, dataout, lenout );
				hexdump( datain, lenin );
#endif

				sync_before_read_align32(datain, lenin);
				switch( datain[0] )
				{
				//	dbgprintf("[%02X]", datain[0] );
					case 0x00:
					{
						W32( (u32)dataout, 0x10110800 );
				//		dbgprintf("Reset(0x%p)\n", dataout );
					} break;
					default:
					// CMD_DIRECT
					case 0x40:
					// CMD_ORIGIN
					case 0x41:
					// CMD_RECALIBRATE
					case 0x42:
					{
						memset( dataout, 0, lenout );
					} break;
				}

				sync_after_write_align32(dataout, lenout);

				//hexdump( dataout, lenout );

				//while( read32(GCAM_CONTROL) & 1 )
				//	clear32( GCAM_CONTROL, 1 );
				
				//while( (read32(GCAM_SSTATUS) & 0x10) != 0x10 )
				//	set32( GCAM_SSTATUS, 0x10 );

			} break;
			case 0x70:
			{
				char	*datain		= (char*)P2C( read32(GCAM_SCMD_1) );
				char	*dataout	= (char*)P2C( read32(GCAM_SCMD_2) );

				//dbgprintf("GC-AM:Command( %p, %u, %p, %u )\n", datain, 0x80, dataout, 0x80 );

				sync_before_read_align32(datain, 0x80);

				memcpy( Bufi, datain, 0x80 );

				GCAMCommand( Bufi, Buf );

				if( FirstCMD == 0 )
				{
					memset32( dataout, 0, 0x80 );
					FirstCMD = 1;
				} else {
					memcpy( dataout, Bufo, 0x80 );
					memcpy( Bufo, Buf, 0x80 );
				}

				sync_after_write_align32(dataout, 0x80);

				//hexdump( dataout, 0x10 );

				//while( read32(GCAM_CONTROL) & 1 )
				//	clear32( GCAM_CONTROL, 1 );
				
				//while( (read32(GCAM_SSTATUS) & 0x10) != 0x10 )
				//	set32( GCAM_SSTATUS, 0x10 );
			} break;
			default:
			{
				dbgprintf("Unhandled cmd:%02X\n", read32(GCAM_SCMD)  );
				Shutdown();
			} break;
		}
		//to be 100% sure we dont ever read a still cached block in ppc
		write32( GCAM_CONTROL, 0xdeadbeef );
		sync_after_write( (void*)GCAM_BASE, 0x40 );
	}
}