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
diff --git a/kitten/arch/x86_64/kernel/sched.c b/kitten/arch/x86_64/kernel/sched.c
new file mode 100644 (file)
index 0000000..522d668
--- /dev/null
@@ -0,0 +1,81 @@
+#include <lwk/kernel.h>
+#include <lwk/smp.h>
+#include <lwk/task.h>
+#include <arch/i387.h>
+
+struct task_struct *
+__arch_context_switch(struct task_struct *prev_p, struct task_struct *next_p)
+{
+       struct thread_struct *prev = &prev_p->arch.thread;
+       struct thread_struct *next = &next_p->arch.thread;
+       id_t cpu = this_cpu;
+       struct tss_struct *tss = &per_cpu(tss, cpu);
+
+       /* Update TSS */
+       tss->rsp0 = next->rsp0;
+
+       /* Switch DS and ES segment registers */
+       asm volatile("mov %%es,%0" : "=m" (prev->es));
+       if (unlikely(next->es | prev->es))
+               loadsegment(es, next->es);
+       asm volatile("mov %%ds,%0" : "=m" (prev->ds));
+       if (unlikely(next->ds | prev->ds))
+               loadsegment(ds, next->ds);
+
+       /* Load FS and GS segment registers (used for thread local storage) */
+       {
+               unsigned int fsindex;
+               asm volatile("movl %%fs,%0" : "=r" (fsindex));
+               if (unlikely(fsindex | next->fsindex | prev->fs)) {
+                       loadsegment(fs, next->fsindex);
+                       if (fsindex)
+                               prev->fs = 0;
+               }
+               if (next->fs)
+                       wrmsrl(MSR_FS_BASE, next->fs);
+               prev->fsindex = fsindex;
+       }
+       {
+               unsigned int gsindex;
+               asm volatile("movl %%gs,%0" : "=r" (gsindex));
+               if (unlikely(gsindex | next->gsindex | prev->gs)) {
+                       load_gs_index(next->gsindex);
+                       if (gsindex)
+                               prev->gs = 0;
+               }
+               if (next->gs)
+                       wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
+               prev->gsindex = gsindex;
+       }
+
+       /* Update the CPU's PDA (per-CPU data area) */
+       write_pda(pcurrent, next_p);
+
+       /* If necessary, save and restore floating-point state */
+       if (prev_p->arch.flags & TF_USED_FPU)
+               fpu_save_state(prev_p);
+       if (next_p->arch.flags & TF_USED_FPU) {
+               clts();
+               fpu_restore_state(next_p);
+       } else {
+               /*
+                * Set the TS flag of CR0 so that FPU/MMX/SSE instructions
+                * will cause a "Device not available" exception. The exception
+                * handler will then initialize the FPU state and set the
+                * task's TF_USED_FPU flag.  From that point on, the task
+                * should never experience another "Device not available"
+                * exception.
+                */
+               stts();
+       }
+
+       return prev_p;
+}
+
+void
+arch_idle_task_loop_body(void)
+{
+       /* Issue HALT instruction,
+        * which should put CPU in a lower power mode */
+       halt();
+}