Esempio n. 1
0
void
RETfar32(void)
{
	descriptor_t sd;
	UINT32 new_ip;
	UINT32 new_cs;
	UINT16 sreg;

	CPU_WORKCLOCK(15);
	if (!CPU_STAT_PM || CPU_STAT_VM86) {
		/* Real mode or VM86 mode */
		CPU_SET_PREV_ESP();
		POP0_32(new_ip);
		POP0_32(new_cs);

		/* check new instrunction pointer with new code segment */
		load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION);
		if (new_ip > sd.u.seg.limit) {
			EXCEPTION(GP_EXCEPTION, 0);
		}

		LOAD_SEGREG(CPU_CS_INDEX, (UINT16)new_cs);
		CPU_EIP = new_ip;
		CPU_CLEAR_PREV_ESP();
	} else {
		/* Protected mode */
		RETfar_pm(0);
	}
}
Esempio n. 2
0
void
IRET(void)
{
	descriptor_t sd;
	UINT32 new_ip;
	UINT32 new_flags;
	UINT32 new_cs;
	UINT32 mask;
	UINT16 sreg;

	CPU_WORKCLOCK(22);
	if (!CPU_STAT_PM) {
		/* Real mode */
		CPU_SET_PREV_ESP();
		mask = I_FLAG|IOPL_FLAG;
		if (!CPU_INST_OP32) {
			POP0_16(new_ip);
			POP0_16(new_cs);
			POP0_16(new_flags);
		} else {
			POP0_32(new_ip);
			POP0_32(new_cs);
			POP0_32(new_flags);
			mask |= RF_FLAG;
		}

		/* check new instrunction pointer with new code segment */
		load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION);
		if (new_ip > sd.u.seg.limit) {
			EXCEPTION(GP_EXCEPTION, 0);
		}

		LOAD_SEGREG(CPU_CS_INDEX, (UINT16)new_cs);
		CPU_EIP = new_ip;

		set_eflags(new_flags, mask);
		CPU_CLEAR_PREV_ESP();
	} else {
		/* Protected mode */
		IRET_pm();
	}
	IRQCHECKTERM();
}
Esempio n. 3
0
void
RETnear32(void)
{
	UINT32 new_ip;

	CPU_WORKCLOCK(11);
	CPU_SET_PREV_ESP();
	POP0_32(new_ip);
	if (new_ip > CPU_STAT_CS_LIMIT) {
		EXCEPTION(GP_EXCEPTION, 0);
	}
	CPU_EIP = new_ip;
	CPU_CLEAR_PREV_ESP();
}
Esempio n. 4
0
void
POPFD_Fd(void)
{
	UINT32 flags, mask;

	CPU_WORKCLOCK(3);
	if (!CPU_STAT_PM) {
		/* Real Mode */
		POP0_32(flags);
		flags &= ~(RF_FLAG|VIF_FLAG|VIP_FLAG);
		mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG;
	} else if (!CPU_STAT_VM86) {
		/* Protected Mode */
		POP0_32(flags);
		flags &= ~RF_FLAG;
		if (CPU_STAT_CPL == 0) {
			flags &= ~(VIP_FLAG|VIF_FLAG);
			mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG;
		} else if (CPU_STAT_CPL <= CPU_STAT_IOPL) {
			flags &= ~(VIP_FLAG|VIF_FLAG);
			mask = I_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG;
		} else {
			mask = RF_FLAG;
		}
	} else if (CPU_STAT_IOPL == CPU_IOPL3) {
		/* Virtual-8086 Mode, IOPL == 3 */
		POP0_32(flags);
		mask = I_FLAG;
	} else {
		EXCEPTION(GP_EXCEPTION, 0);
		flags = 0;
		mask = 0;
		/* compiler happy */
	}
	set_eflags(flags, mask);
	IRQCHECKTERM();
}
Esempio n. 5
0
void
LEAVE(void)
{

	CPU_WORKCLOCK(4);

	CPU_SET_PREV_ESP();
	if (!CPU_STAT_SS32) {
		CPU_SP = CPU_BP;
	} else {
		CPU_ESP = CPU_EBP;
	}
	if (!CPU_INST_OP32) {
		POP0_16(CPU_BP);
	} else {
		POP0_32(CPU_EBP);
	}
	CPU_CLEAR_PREV_ESP();
}
Esempio n. 6
0
void
RETnear32_Iw(void)
{
	UINT32 new_ip;
	UINT16 size;

	CPU_WORKCLOCK(11);
	CPU_SET_PREV_ESP();
	GET_PCWORD(size);
	POP0_32(new_ip);
	if (new_ip > CPU_STAT_CS_LIMIT) {
		EXCEPTION(GP_EXCEPTION, 0);
	}
	CPU_EIP = new_ip;
	if (!CPU_STAT_SS32) {
		CPU_SP += size;
	} else {
		CPU_ESP += size;
	}
	CPU_CLEAR_PREV_ESP();
}