5 EXTENSION class Context
8 enum { Gdt_user_entries = 4 };
9 Gdt_entry _gdt_user_entries[Gdt_user_entries];
10 Unsigned32 _es, _fs, _gs;
14 //-----------------------------------------------------------------------------
20 PROTECTED inline NEEDS ["cpu.h", "gdt.h"]
22 Context::switch_gdt_user_entries(Context *to)
24 Gdt &gdt = *Cpu::cpus.cpu(to->cpu()).get_gdt();
25 for (unsigned i = 0; i < Gdt_user_entries; ++i)
26 gdt[(Gdt::gdt_user_entry1 / 8) + i] = to->_gdt_user_entries[i];
30 //---------------------------------------------------------------------------
31 IMPLEMENTATION [ia32 || ux]:
34 IMPLEMENT inline NEEDS [Context::update_consumed_time,
35 Context::store_segments]
37 Context::switch_cpu (Context *t)
39 Mword dummy1, dummy2, dummy3, dummy4;
41 update_consumed_time();
45 switch_gdt_user_entries(t);
49 " pushl %%ebp \n\t" // save base ptr of old thread
50 " pushl $1f \n\t" // restart addr to old stack
51 " movl %%esp, (%0) \n\t" // save stack pointer
52 " movl (%1), %%esp \n\t" // load new stack pointer
53 // in new context now (cli'd)
54 " movl %2, %%eax \n\t" // new thread's "this"
55 " call switchin_context_label \n\t" // switch pagetable
56 " popl %%eax \n\t" // don't do ret here -- we want
57 " jmp *%%eax \n\t" // to preserve the return stack
59 " .p2align 4 \n\t" // start code at new cache line
60 "1: popl %%ebp \n\t" // restore base ptr
62 : "=c" (dummy1), "=S" (dummy2), "=D" (dummy3), "=d" (dummy4)
63 : "c" (&_kernel_sp), "S" (&t->_kernel_sp), "D" (t), "d" (this)
64 : "eax", "ebx", "memory");