static void
std8250_io_do_cycle (void * state)
{
	const int core_id = 0; /* currently, we only send uart interrupt to cpu0 */
        e500_core_t * core = get_boot_core();

        mpc8641d_io_t *io = &mpc8641d_io;

	std_16550_uart_t *uart = &io->uart[0];
	/*
	   if(!(core->msr & 0x8000)) 
	   return;
	 */
	if (uart->iir & 0x1) {
		if (uart->ier & 0x2) {	/* THREI enabled */
			//printf("In %s, THR interrupt\n", __FUNCTION__);
			uart->iir = (uart->iir & 0xf0) | 0x2;
			uart->lsr |= 0x60;
		}

		if (uart->ier & 0x1) {	/* RDAI enabled */
			struct timeval tv;
			unsigned char c;

			tv.tv_sec = 0;
			tv.tv_usec = 0;
			if (skyeye_uart_read (-1, &c, 1, &tv, NULL) > 0) {
				uart->rbr = (int) c;
				//printf("SKYEYE: io_do_cycle  set ffiir  or 04, now %x\n",pxa250_io.ffiir);
				uart->lsr |= 0x01;	//Data ready
				uart->iir = (uart->iir & 0xf0) | 0x4;
			}
		}
	}
	if ((!(io->mpic.iivpr[UART_IRQ] & 0x80000000) && (core->msr & 0x8000)
	     && !(core->ipr & 1 << UART_IRQ))) {
		//if(!(io->mpic.iivpr[UART_IRQ] & 0x80000000)){
		if ((!(uart->iir & 0x1)) && (uart->ier & 0x3)
			) {
			//printf ("In %s,uart int triggered. ier=0x%x\n",	__FUNCTION__, uart->ier);
			core->ipr |= (1 << UART_IRQ);
			io->mpic.iivpr[UART_IRQ] |= 0x40000000;	/* set activity bit in vpr */
			io->pic_percpu.iack[core_id] =
				(io->pic_percpu.
				 iack[core_id] & 0xFFFF0000) | (io->mpic.
								ipivpr
								[UART_IRQ] &
								0xFFFF);
			skyeye_config_t *config = get_current_config();
			if (!strcmp(config->os->os_name, "linux")) {
				io->pic_percpu.iack[core_id] = 0x2a;
			}else if (!strcmp(config->os->os_name, "vxworks")) {
				io->pic_percpu.iack[core_id] = 0x26;
			}
			//printf("In %s, ack=0x%x\n", __FUNCTION__, io->pic_percpu.iack[core_id]);
			core->ipi_flag = 1;	/* we need to inform the core that npc is changed to exception vector */
			ppc_exception (core, PPC_EXC_EXT_INT, 0, 0);
		}
	}
}
Beispiel #2
0
// main opcode 63
static void ppc_opc_group_f2()
{
	if ((gCPU.msr & MSR_FP) == 0) {
		ppc_exception(PPC_EXC_NO_FPU);
		return;
	}
	uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
	if (ext & 16) {
		switch (ext & 0x1f) {
		case 18: ppc_opc_fdivx(); return;
		case 20: ppc_opc_fsubx(); return;
		case 21: ppc_opc_faddx(); return;
		case 22: ppc_opc_fsqrtx(); return;
		case 23: ppc_opc_fselx(); return;
		case 25: ppc_opc_fmulx(); return;
		case 26: ppc_opc_frsqrtex(); return;
		case 28: ppc_opc_fmsubx(); return;
		case 29: ppc_opc_fmaddx(); return;
		case 30: ppc_opc_fnmsubx(); return;
		case 31: ppc_opc_fnmaddx(); return;
		}
	} else {
		switch (ext) {
		case 0: ppc_opc_fcmpu(); return;
		case 12: ppc_opc_frspx(); return;
		case 14: ppc_opc_fctiwx(); return;
		case 15: ppc_opc_fctiwzx(); return;
		//--
		case 32: ppc_opc_fcmpo(); return;
		case 38: ppc_opc_mtfsb1x(); return;
		case 40: ppc_opc_fnegx(); return;
		case 64: ppc_opc_mcrfs(); return;
		case 70: ppc_opc_mtfsb0x(); return;
		case 72: ppc_opc_fmrx(); return;
		case 134: ppc_opc_mtfsfix(); return;
		case 136: ppc_opc_fnabsx(); return;
		case 264: ppc_opc_fabsx(); return;
		case 583: ppc_opc_mffsx(); return;
		case 711: ppc_opc_mtfsfx(); return;
		}
	}
	ppc_opc_invalid();
}
Beispiel #3
0
// main opcode 59
static void ppc_opc_group_f1()
{
	if ((gCPU.msr & MSR_FP) == 0) {
		ppc_exception(PPC_EXC_NO_FPU);
		return;
	}
	uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
	switch (ext & 0x1f) {
		case 18: ppc_opc_fdivsx(); return;
		case 20: ppc_opc_fsubsx(); return;
		case 21: ppc_opc_faddsx(); return;
		case 22: ppc_opc_fsqrtsx(); return;
		case 24: ppc_opc_fresx(); return;
		case 25: ppc_opc_fmulsx(); return;
		case 28: ppc_opc_fmsubsx(); return;
		case 29: ppc_opc_fmaddsx(); return;
		case 30: ppc_opc_fnmsubsx(); return;
		case 31: ppc_opc_fnmaddsx(); return;
	}
	ppc_opc_invalid();
}
Beispiel #4
0
// main opcode 04
static void ppc_opc_group_v()
{
	uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
#ifndef  __VEC_EXC_OFF__
	if ((gCPU.msr & MSR_VEC) == 0) {
		ppc_exception(PPC_EXC_NO_VEC);
		return;
	}
#endif
	switch(ext & 0x1f) {
		case 16:
			if (gCPU.current_opc & PPC_OPC_Rc)
				return ppc_opc_vmhraddshs();
			else
				return ppc_opc_vmhaddshs();
		case 17:	return ppc_opc_vmladduhm();
		case 18:
			if (gCPU.current_opc & PPC_OPC_Rc)
				return ppc_opc_vmsummbm();
			else
				return ppc_opc_vmsumubm();
		case 19:
			if (gCPU.current_opc & PPC_OPC_Rc)
				return ppc_opc_vmsumuhs();
			else
				return ppc_opc_vmsumuhm();
		case 20:
			if (gCPU.current_opc & PPC_OPC_Rc)
				return ppc_opc_vmsumshs();
			else
				return ppc_opc_vmsumshm();
		case 21:
			if (gCPU.current_opc & PPC_OPC_Rc)
				return ppc_opc_vperm();
			else
				return ppc_opc_vsel();
		case 22:	return ppc_opc_vsldoi();
		case 23:
			if (gCPU.current_opc & PPC_OPC_Rc)
				return ppc_opc_vnmsubfp();
			else
				return ppc_opc_vmaddfp();
	}
	switch(ext & 0x1ff)
	{
		case 3: return ppc_opc_vcmpequbx();
		case 35: return ppc_opc_vcmpequhx();
		case 67: return ppc_opc_vcmpequwx();
		case 99: return ppc_opc_vcmpeqfpx();
		case 227: return ppc_opc_vcmpgefpx();
		case 259: return ppc_opc_vcmpgtubx();
		case 291: return ppc_opc_vcmpgtuhx();
		case 323: return ppc_opc_vcmpgtuwx();
		case 355: return ppc_opc_vcmpgtfpx();
		case 387: return ppc_opc_vcmpgtsbx();
		case 419: return ppc_opc_vcmpgtshx();
		case 451: return ppc_opc_vcmpgtswx();
		case 483: return ppc_opc_vcmpbfpx();
	}

	if (ext >= (sizeof ppc_opc_table_groupv / sizeof ppc_opc_table_groupv[0])) {
		return ppc_opc_invalid();
	}
	return ppc_opc_table_groupv[ext]();
}
Beispiel #5
0
void ppc_cpu_run()
{
	/*gDebugger = new Debugger();
	gDebugger->mAlwaysShowRegs = true;*/
	PPC_CPU_TRACE("execution started at %08x\n", current_core->pc);
	uint ops=0;
	current_core->effective_code_page = 0xffffffff;
//	ppc_fpu_test();
//	return;
	while (true) {
		current_core->npc = current_core->pc+4;
		if ((current_core->pc & ~0xfff) == current_core->effective_code_page) {
			current_core->current_opc = ppc_word_from_BE(*((uint32*)(&current_core->physical_code_page[current_core->pc & 0xfff])));
			ppc_debug_hook();
		} else {
			int ret;
			if ((ret = ppc_direct_effective_memory_handle_code(current_core->pc & ~0xfff, current_core->physical_code_page))) {
				if (ret == PPC_MMU_EXC) {
					current_core->pc = current_core->npc;
					continue;
				} else {
					PPC_CPU_ERR("?\n");
				}
			}
			current_core->effective_code_page = current_core->pc & ~0xfff;
			continue;
		}
		ppc_exec_opc();
		ops++;
		current_core->ptb++;
		if (current_core->pdec == 0) {
			current_core->exception_pending = true;
			current_core->dec_exception = true;
			current_core->pdec=0xffffffff*TB_TO_PTB_FACTOR;
		} else {
			current_core->pdec--;
		}
		if ((ops & 0x3ffff)==0) {
/*			if (pic_check_interrupt()) {
				current_core->exception_pending = true;
				current_core->ext_exception = true;
			}*/
			if ((ops & 0x0fffff)==0) {
//				uint32 j=0;
//				ppc_read_effective_word(0xc046b2f8, j);

				ht_printf("@%08x (%u ops) pdec: %08x lr: %08x\r", current_core->pc, ops, current_core->pdec, current_core->lr);
#if 0
				extern uint32 PIC_enable_low;
				extern uint32 PIC_enable_high;
				ht_printf("enable ");
				int x = 1;
				for (int i=0; i<31; i++) {
					if (PIC_enable_low & x) {
						ht_printf("%d ", i);
		    			}
					x<<=1;
				}
				x=1;
				for (int i=0; i<31; i++) {
					if (PIC_enable_high & x) {
						ht_printf("%d ", 32+i);
		    			}
					x<<=1;
				}
				ht_printf("\n");
#endif
			}
		}
		
		current_core->pc = current_core->npc;
		
		if (current_core->exception_pending) {
			if (current_core->stop_exception) {
				current_core->stop_exception = false;
				if (!current_core->dec_exception && !current_core->ext_exception) current_core->exception_pending = false;
				break;
			}
			if (current_core->msr & MSR_EE) {
				/*sys_lock_mutex(exception_mutex);*/
				if (current_core->ext_exception) {
					ppc_exception(current_core, PPC_EXC_EXT_INT,0,0);
					current_core->ext_exception = false;
					current_core->pc = current_core->npc;
					if (!current_core->dec_exception) current_core->exception_pending = false;
					/*sys_unlock_mutex(exception_mutex);*/
					continue;
				}
				if (current_core->dec_exception) {
					ppc_exception(current_core, PPC_EXC_DEC,0,0);
					current_core->dec_exception = false;
					current_core->pc = current_core->npc;
					current_core->exception_pending = false;
					/*sys_unlock_mutex(exception_mutex);*/
					continue;
				}
				/*sys_unlock_mutex(exception_mutex);*/
				PPC_CPU_ERR("no interrupt, but signaled?!\n");
			}
		}
#ifdef PPC_CPU_ENABLE_SINGLESTEP
		if (current_core->msr & MSR_SE) {
			if (current_core->singlestep_ignore) {
				current_core->singlestep_ignore = false;
			} else {
				ppc_exception(current_core, PPC_EXC_TRACE2);
				current_core->pc = current_core->npc;
				continue;
			}
		}
#endif
	}
}