Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / kernel / sched.c
1 #include <lwk/kernel.h>
2 #include <lwk/smp.h>
3 #include <lwk/task.h>
4 #include <arch/i387.h>
5
6 struct task_struct *
7 __arch_context_switch(struct task_struct *prev_p, struct task_struct *next_p)
8 {
9         struct thread_struct *prev = &prev_p->arch.thread;
10         struct thread_struct *next = &next_p->arch.thread;
11         id_t cpu = this_cpu;
12         struct tss_struct *tss = &per_cpu(tss, cpu);
13
14         /* Update TSS */
15         tss->rsp0 = next->rsp0;
16
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);
24
25         /* Load FS and GS segment registers (used for thread local storage) */
26         {
27                 unsigned int fsindex;
28                 asm volatile("movl %%fs,%0" : "=r" (fsindex));
29                 if (unlikely(fsindex | next->fsindex | prev->fs)) {
30                         loadsegment(fs, next->fsindex);
31                         if (fsindex)
32                                 prev->fs = 0;
33                 }
34                 if (next->fs)
35                         wrmsrl(MSR_FS_BASE, next->fs);
36                 prev->fsindex = fsindex;
37         }
38         {
39                 unsigned int gsindex;
40                 asm volatile("movl %%gs,%0" : "=r" (gsindex));
41                 if (unlikely(gsindex | next->gsindex | prev->gs)) {
42                         load_gs_index(next->gsindex);
43                         if (gsindex)
44                                 prev->gs = 0;
45                 }
46                 if (next->gs)
47                         wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
48                 prev->gsindex = gsindex;
49         }
50
51         /* Update the CPU's PDA (per-CPU data area) */
52         write_pda(pcurrent, next_p);
53
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) {
58                 clts();
59                 fpu_restore_state(next_p);
60         } else {
61                 /*
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"
67                  * exception.
68                  */
69                 stts();
70         }
71
72         return prev_p;
73 }
74
75 void
76 arch_idle_task_loop_body(void)
77 {
78         /* Issue HALT instruction,
79          * which should put CPU in a lower power mode */
80         halt();
81 }