/* * Task dispatcher. Basically it may be the same one no matter what scheduling algorithm is used */ void core_Dispatch(regs_t *regs) { volatile struct ExecBase *SysBase = getSysBase(); struct Task *task; if (SysBase) { wrmsr(rdmsr() & ~MSR_EE); /* * Is the list of ready tasks empty? Well, increment the idle switch cound and halt CPU. * It should be extended by some plugin mechanism which would put CPU and whole machine * into some more sophisticated sleep states (ACPI?) */ while (IsListEmpty(&SysBase->TaskReady)) { // SysBase->IdleCount++; SysBase->AttnResched |= ARF_AttnSwitch; //D(bug("[KRN] TaskReady list empty. Sleeping for a while...\n")); /* Sleep almost forever ;) */ wrmsr(rdmsr() | MSR_EE); asm volatile("sync"); // wrmsr(rdmsr() | MSR_POW); // asm volatile("isync"); if (SysBase->SysFlags & SFF_SoftInt) { core_Cause(SysBase); } } SysBase->DispCount++; /* Get the first task from the TaskReady list, and populate it's settings through Sysbase */ task = (struct Task *)REMHEAD(&SysBase->TaskReady); SysBase->ThisTask = task; SysBase->Elapsed = SysBase->Quantum; SysBase->SysFlags &= ~0x2000; task->tc_State = TS_RUN; SysBase->IDNestCnt = task->tc_IDNestCnt; //D(bug("[KRN] New task = %p (%s)\n", task, task->tc_Node.ln_Name)); /* Handle tasks's flags */ if (task->tc_Flags & TF_EXCEPT) Exception(); /* Store the launch time */ GetIntETask(task)->iet_private1 = mftbu(); if (task->tc_Flags & TF_LAUNCH) { AROS_UFC1(void, task->tc_Launch, AROS_UFCA(struct ExecBase *, SysBase, A6)); } /* Restore the task's state */ regs = task->tc_UnionETask.tc_ETask->et_RegFrame; if (SysBase->IDNestCnt < 0) regs->srr1 |= MSR_EE; /* Copy the fpu, mmx, xmm state */ #warning FIXME: Change to the lazy saving of the FPU state!!!! #warning TODO: No FPU support yet!!!!!!! Yay, it sucks! :-D }
return retval; AROS_LIBFUNC_EXIT } AROS_LH4(void *, KrnAddExceptionHandler, AROS_LHA(uint8_t, irq, D0), AROS_LHA(void *, handler, A0), AROS_LHA(void *, handlerData, A1), AROS_LHA(void *, handlerData2, A2), struct KernelBase *, KernelBase, 7, Kernel) { AROS_LIBFUNC_INIT struct ExecBase *SysBase = getSysBase(); struct ExceptNode *handle = NULL; D(bug("[KRN] KrnAddExceptionHandler(%02x, %012p, %012p, %012p):\n", irq, handler, handlerData, handlerData2)); if (irq < 21) { /* Go to supervisor mode */ goSuper(); handle = Allocate(KernelBase->kb_SupervisorMem, sizeof(struct ExceptNode)); D(bug("[KRN] handle=%012p\n", handle)); if (handle) { handle->in_Handler = handler; handle->in_HandlerData = handlerData;