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) ); }
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) ); }