1 #include <lwk/kernel.h>
7 __arch_context_switch(struct task_struct *prev_p, struct task_struct *next_p)
9 struct thread_struct *prev = &prev_p->arch.thread;
10 struct thread_struct *next = &next_p->arch.thread;
12 struct tss_struct *tss = &per_cpu(tss, cpu);
15 tss->rsp0 = next->rsp0;
17 /* Switch DS and ES segment registers */
18 asm volatile("mov %%es,%0" : "=m" (prev->es));
19 if (unlikely(next->es | prev->es))
20 loadsegment(es, next->es);
21 asm volatile("mov %%ds,%0" : "=m" (prev->ds));
22 if (unlikely(next->ds | prev->ds))
23 loadsegment(ds, next->ds);
25 /* Load FS and GS segment registers (used for thread local storage) */
28 asm volatile("movl %%fs,%0" : "=r" (fsindex));
29 if (unlikely(fsindex | next->fsindex | prev->fs)) {
30 loadsegment(fs, next->fsindex);
35 wrmsrl(MSR_FS_BASE, next->fs);
36 prev->fsindex = fsindex;
40 asm volatile("movl %%gs,%0" : "=r" (gsindex));
41 if (unlikely(gsindex | next->gsindex | prev->gs)) {
42 load_gs_index(next->gsindex);
47 wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
48 prev->gsindex = gsindex;
51 /* Update the CPU's PDA (per-CPU data area) */
52 write_pda(pcurrent, next_p);
54 /* If necessary, save and restore floating-point state */
55 if (prev_p->arch.flags & TF_USED_FPU)
56 fpu_save_state(prev_p);
57 if (next_p->arch.flags & TF_USED_FPU) {
59 fpu_restore_state(next_p);
62 * Set the TS flag of CR0 so that FPU/MMX/SSE instructions
63 * will cause a "Device not available" exception. The exception
64 * handler will then initialize the FPU state and set the
65 * task's TF_USED_FPU flag. From that point on, the task
66 * should never experience another "Device not available"
76 arch_idle_task_loop_body(void)
78 /* Issue HALT instruction,
79 * which should put CPU in a lower power mode */