/**************************************************************************************
Copyright (c) 2002
The UbixOS Project
$Id$
**************************************************************************************/
#include <ubixos/schedule.h>
#include <ubixos/io.h>
#include <ubixos/gdt.h>
#include <ubixos/idt.h>
#include <drivers/8259.h>
#include <drivers/video.h>
int currentProc;
struct taskStruct taskList[numTasks];
struct taskStruct *_current,*_usedMath = 0x0;
extern union descriptorTableunion GDT[7];
extern int testVal;
/* Initialize Scheduler */
void initScheduler(void) {
int i;
for (i=0;i<numTasks;i++) {
taskList[i].id = i;
taskList[i].status = AVAILABLE;
taskList[i].usedMath = 0;
}
currentProc = -1;
setVector(timerInt, mVec, (dInt + dPresent + dDpl3));
outportByte(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */
outportByte(LATCH & 0xff , 0x40); /* LSB */
outportByte(LATCH >> 8 , 0x40); /* MSB */
}
/* Finds A Free Task */
int findTask() {
int i;
for (i=0;i<numTasks;i++) {
if (taskList[i].status == AVAILABLE) {
return(i);
}
}
return(-1);
}
void schedule() {
int i,proc = -1,memAddr;
outportByte(0x20, 0x20);
for (i=currentProc;i<numTasks;i++) {
if (taskList[i].status == RUNABLE) {
proc = i;
break;
}
else if ((taskList[i].status == ACTIVE) && (i != currentProc)) {
proc = i;
break;
}
if (i+1 >= numTasks) { i = -1; }
}
if (proc != -1) {
currentProc = proc;
_current = &taskList[proc];
taskList[proc].status = ACTIVE;
memAddr = (unsigned int)&taskList[proc].tss;
GDT[4].descriptor.access = 0x89;
GDT[4].descriptor.baseLow = (memAddr & 0xFFFF);
GDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xff);
GDT[4].descriptor.baseHigh = (memAddr >> 24);
kprintf("Switch To Task; [%i][%i]\n",proc,testVal);
asm("ljmp $0x20,$0\n");
}
}
/* Timer Interupt */
asm (
".globl timerInt \n"
"timerInt: \n"
" pusha \n"
" call schedule \n"
" popa \n"
" iret \n"
);