Beispiel #1
0
void
context_switch(context_t *oldc, context_t *newc)
{
        gdt_set_kernel_stack((void *)((uintptr_t)newc->c_kstack + newc->c_kstacksz));
        pt_set(newc->c_pdptr);

        /*
         * Save the current value of the stack pointer and the frame pointer into
         * the old context. Set the instruction pointer to the return address
         * (whoever called us).
         */
        __asm__ __volatile__(
                "pushfl           \n\t" /* save EFLAGS on the stack */
                "pushl  %%ebp     \n\t"
                "movl   %%esp, %0 \n\t" /* save ESP into oldc */
                "movl   %2, %%esp \n\t" /* restore ESP from newc */
                "movl   $1f, %1   \n\t" /* save EIP into oldc */
                "pushl  %3        \n\t" /* restore EIP */
                "ret              \n\t"
                "1:\t"                  /* this is where oldc starts executing later */
                "popl   %%ebp     \n\t"
                "popfl"                 /* restore EFLAGS */
                :"=m"(oldc->c_esp), "=m"(oldc->c_eip)
                :"m"(newc->c_esp), "m"(newc->c_eip)
        );
}
Beispiel #2
0
void
context_make_active(context_t *c)
{
        gdt_set_kernel_stack((void *)((uintptr_t)c->c_kstack + c->c_kstacksz));
        pt_set(c->c_pdptr);

        /* Switch stacks and run the thread */
        __asm__ volatile(
                "movl %0,%%ebp\n\t"     /* update ebp */
                "movl %1,%%esp\n\t"     /* update esp */
                "push %2\n\t"           /* save eip   */
                "ret"                   /* jump to new eip */
                :: "m"(c->c_ebp), "m"(c->c_esp), "m"(c->c_eip)
        );
}