Example #1
0
void switch_if_needed(uint32_t ticks) {
    task_t *current = current_task();
    current->rem_quantum--;
    current->ticks++;

    if (!current->rem_quantum) {
        restart_quantum(current);
        switch_tasks();
    }
}
Example #2
0
File: emu.c Project: aunali1/exopc
int emu_iret(unsigned char *lina)
{
    trace("iret\n");

    if (! opa.pe) {
	Bit32u tmp;
	int width = opa.opb;
	
	if (REG(esp) > 0x10000 - 3*width) {
	    set_guest_exc(12, 0);
	    goto exc;
	}
	if (get_memory(LWORD(ss), LWORD(esp), &REG(eip), width))
	    goto exc;
	if (width == 2)
	    REG(eip) &= 0xffff;
	LWORD(esp) += width;
	if (get_memory(LWORD(ss), LWORD(esp), &tmp, 2))  /* always only use 16 bits */
	    goto exc;
	REG(cs) = tmp;
	LWORD(esp) += width;
	if (get_memory(LWORD(ss), LWORD(esp), &tmp, width))
	    goto exc;
	LWORD(eflags) = tmp;
	LWORD(esp) += width;
	
	if (width == 4) {
	    /* 32 bit -- VM, IOPL, VIP, and VIF are unmodified */
	    REG(eflags) = ((tmp        & ~(VM_MASK | IOPL_MASK | VIP_MASK | VIF_MASK)) |
			   (REG(eflags) & (VM_MASK | IOPL_MASK | VIP_MASK | VIF_MASK)));
	} else {
	    /* 16 bit -- IOPL is unmodified */
	    REG(eflags) = ((tmp        & ~(0xffff000 | IOPL_MASK)) |
			   (REG(eflags) & (0xffff000 | IOPL_MASK)));
	}
	
	trace("%d byte iret; eip=%x cs=%x, eflags=%x; new lina=%x\n", opa.opb,
	      REG(eip), REG(cs), REG(eflags), (u_int)lina);
    } else {
	/* PROTECTED-MODE */

	if (REG(eflags) & NT_MASK) {
	    /* TASK-RETURN */
	    Bit16u old_sel = vmstate.tr_sel;
	    struct seg_descr *old_tss;
	    struct Ts *ts = (struct Ts*)vmstate.tr_base;
	    struct seg_descr tss;
	    Bit16u selector = ts->ts_link;
	    int err;

	    if (get_tss_descriptor(selector, &tss, 1) ||
		switch_tasks(selector, &tss))
		goto exc;
	    
	    ts->ts_t = 0; /* We probably got here because this was set, to let us emulate it. */

	    /* mark the descriptor of the abandoned task as "not busy" */
	    ASSERT((old_sel & ~7) == 0);
	    ASSERT((old_sel & ~7) >= vmstate.g_gdt_limit);
	    err = set_get_any(&vmstate.g_gdt_base, (u_int*)&old_tss);
	    ASSERT(!err);
	    old_tss += (old_sel >> 3);
	    old_tss->type &= ~2;
	} else {