revert between 56095 -> 55830 in arch
[AROS.git] / arch / i386-pc / kernel / kernel_cpu.c
blob35b06da5a9583645f71b06959b6f14fff906c6ba
1 /*
2 Copyright © 2011-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: i386 native CPU supplementals for task scheduler
6 Lang: english
7 */
9 #include <exec/lists.h>
10 #include <exec/tasks.h>
11 #include <exec/execbase.h>
12 #include <hardware/intbits.h>
13 #include <proto/exec.h>
15 #include "etask.h"
17 #include "kernel_base.h"
18 #include "kernel_debug.h"
19 #include "kernel_intern.h"
20 #include "kernel_intr.h"
21 #include "kernel_scheduler.h"
23 #include "apic.h"
25 #define D(x)
27 void cpu_Dispatch(struct ExceptionContext *regs)
29 struct Task *task;
30 struct ExceptionContext *ctx;
32 /*
33 * Is the list of ready tasks empty? Well, increment the idle switch count and halt CPU.
34 * It should be extended by some plugin mechanism which would put CPU and whole machine
35 * into some more sophisticated sleep states (ACPI?)
37 while (!(task = core_Dispatch()))
39 /* Sleep almost forever ;) */
40 __asm__ __volatile__("sti; hlt; cli");
42 if (SysBase->SysFlags & SFF_SoftInt)
43 core_Cause(INTB_SOFTINT, 1l << INTB_SOFTINT);
46 /* TODO: Handle exception
47 if (task->tc_Flags & TF_EXCEPT)
48 Exception(); */
50 /* Get task's context */
51 ctx = task->tc_UnionETask.tc_ETask->et_RegFrame;
52 D(bug("[Kernel] Dispatch task %s, context 0x%p\n", task->tc_Node.ln_Name, ctx));
54 /* Restore GPRs first. CopyMemQuick() may use SSE. */
55 CopyMemQuick(ctx, regs, offsetof(struct ExceptionContext, FPData));
56 /* Then FPU */
57 if (ctx->Flags & ECF_FPX)
60 * We have SSE state, restore it.
61 * SSE context includes 8087, so we don't have to care about
62 * it separately after this.
64 asm volatile("fxrstor (%0)"::"r"(ctx->FXData));
66 else if (ctx->Flags & ECF_FPU)
68 /* No SSE, plain 8087 */
69 asm volatile("frstor (%0)"::"r"(ctx->FPData));
72 /* Store the launch time */
73 GetIntETask(task)->iet_private1 = RDTSC();
76 void cpu_Switch(struct ExceptionContext *regs)
78 struct Task *task = SysBase->ThisTask;
79 struct ExceptionContext *ctx = task->tc_UnionETask.tc_ETask->et_RegFrame;
81 D(bug("[Kernel] cpu_Switch(), task %s\n", task->tc_Node.ln_Name));
83 /*
84 * Copy the fpu, mmx, xmm state.
85 * Do this before CopyMemQuick(), because this function
86 * can use SSE itself.
88 if (KernelBase->kb_ContextFlags & ECF_FPX)
89 asm volatile("fxsave (%0)"::"r"(ctx->FXData));
90 if (KernelBase->kb_ContextFlags & ECF_FPU)
91 asm volatile("fnsave (%0)"::"r"(ctx->FPData));
94 * Copy current task's context into the ETask structure. Note that context on stack
95 * misses SSE data pointer.
97 CopyMemQuick(regs, ctx, offsetof(struct ExceptionContext, FPData));
98 /* We have the complete data now */
99 ctx->Flags = ECF_SEGMENTS | KernelBase->kb_ContextFlags;
100 /* Set task's tc_SPReg */
101 task->tc_SPReg = (APTR)regs->esp;
103 /* FIXME */
104 #if (0)
105 GetIntETask(task)->iet_CpuTime += (RDTSC() - GetIntETask(task)->iet_private1);
106 #endif
108 core_Switch();