X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=palacios%2Fsrc%2Fgeekos%2Ftimer.c;fp=palacios%2Fsrc%2Fgeekos%2Ftimer.c;h=0000000000000000000000000000000000000000;hp=cd89f863be53c8fa7715af7066b864f47145d975;hb=ddc16b0737cf58f7aa90a69c6652cdf4090aec51;hpb=626595465a2c6987606a6bc697df65130ad8c2d3 diff --git a/palacios/src/geekos/timer.c b/palacios/src/geekos/timer.c deleted file mode 100644 index cd89f86..0000000 --- a/palacios/src/geekos/timer.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * GeekOS timer interrupt support - * Copyright (c) 2001,2003 David H. Hovemeyer - * Copyright (c) 2003, Jeffrey K. Hollingsworth - * $Revision: 1.1 $ - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "COPYING". - */ - -#include -#include -#include -#include -#include -#include - -#include - -#define HZ 100 - - -/* - * Global tick counter - */ -volatile ulong_t g_numTicks; - -/* - * Number of times the spin loop can execute during one timer tick - */ -static int s_spinCountPerTick; - -/* - * Number of ticks to wait before calibrating the delay loop. - */ -#define CALIBRATE_NUM_TICKS 3 - -/* - * The default quantum; maximum number of ticks a thread can use before - * we suspend it and choose another. - */ -#define DEFAULT_MAX_TICKS 4 - -/* - * Settable quantum. - */ -int g_Quantum = DEFAULT_MAX_TICKS; - -/* - * Ticks per second. - * FIXME: should set this to something more reasonable, like 100. - */ -#define TICKS_PER_SEC 18 - -/*#define DEBUG_TIMER */ -#ifdef DEBUG_TIMER -# define Debug(args...) Print(args) -#else -# define Debug(args...) -#endif - -/* ---------------------------------------------------------------------- - * Private functions - * ---------------------------------------------------------------------- */ - -static void Timer_Interrupt_Handler(struct Interrupt_State* state) -{ - struct Kernel_Thread* current = g_currentThread; - - Begin_IRQ(state); - - SerialPrintLevel(10,"Host Timer Interrupt Handler Running\n"); - - /* Update global and per-thread number of ticks */ - ++g_numTicks; - ++current->numTicks; - - - /* - * If thread has been running for an entire quantum, - * inform the interrupt return code that we want - * to choose a new thread. - */ - if (current->numTicks >= g_Quantum) { - g_needReschedule = true; - } - - - End_IRQ(state); -} - -/* - * Temporary timer interrupt handler used to calibrate - * the delay loop. - */ -static void Timer_Calibrate(struct Interrupt_State* state) -{ - Begin_IRQ(state); - if (g_numTicks < CALIBRATE_NUM_TICKS) - ++g_numTicks; - else { - /* - * Now we can look at EAX, which reflects how many times - * the loop has executed - */ - /*Print("Timer_Calibrate: eax==%d\n", state->eax);*/ - s_spinCountPerTick = INT_MAX - state->eax; - state->eax = 0; /* make the loop terminate */ - } - End_IRQ(state); -} - -/* - * Delay loop; spins for given number of iterations. - */ -static void Spin(int count) -{ - /* - * The assembly code is the logical equivalent of - * while (count-- > 0) { // waste some time } - * We rely on EAX being used as the counter - * variable. - */ - - int result; - __asm__ __volatile__ ( - "1: decl %%eax\n\t" - "cmpl $0, %%eax\n\t" - "nop; nop; nop; nop; nop; nop\n\t" - "nop; nop; nop; nop; nop; nop\n\t" - "jg 1b" - : "=a" (result) - : "a" (count) - ); -} - -/* - * Calibrate the delay loop. - * This will initialize s_spinCountPerTick, which indicates - * how many iterations of the loop are executed per timer tick. - */ -static void Calibrate_Delay(void) -{ - Disable_Interrupts(); - - /* Install temporarily interrupt handler */ - Install_IRQ(TIMER_IRQ, &Timer_Calibrate); - Enable_IRQ(TIMER_IRQ); - - Enable_Interrupts(); - - /* Wait a few ticks */ - while (g_numTicks < CALIBRATE_NUM_TICKS) - ; - - /* - * Execute the spin loop. - * The temporary interrupt handler will overwrite the - * loop counter when the next tick occurs. - */ - Spin(INT_MAX); - - Disable_Interrupts(); - - /* - * Mask out the timer IRQ again, - * since we will be installing a real timer interrupt handler. - */ - Disable_IRQ(TIMER_IRQ); - Enable_Interrupts(); -} - -/* ---------------------------------------------------------------------- - * Public functions - * ---------------------------------------------------------------------- */ - -void Init_Timer(void) -{ - ushort_t foo = 1193182L / HZ; - - PrintBoth("Initializing timer and setting to %d Hz...\n",HZ); - - /* Calibrate for delay loop */ - Calibrate_Delay(); - PrintBoth("Delay loop: %d iterations per tick\n", s_spinCountPerTick); - - // Set Timer to HZ - - Out_Byte(0x43,0x36); // channel 0, LSB/MSB, mode 3, binary - Out_Byte(0x40, foo & 0xff); // LSB - Out_Byte(0x40, foo >>8); // MSB - - /* Install an interrupt handler for the timer IRQ */ - - Install_IRQ(TIMER_IRQ, &Timer_Interrupt_Handler); - Enable_IRQ(TIMER_IRQ); -} - - -#define US_PER_TICK (TICKS_PER_SEC * 1000000) - -/* - * Spin for at least given number of microseconds. - * FIXME: I'm sure this implementation leaves a lot to - * be desired. - */ -void Micro_Delay(int us) -{ - int num = us * s_spinCountPerTick; - int denom = US_PER_TICK; - - int numSpins = num / denom; - int rem = num % denom; - - if (rem > 0) - ++numSpins; - - Debug("Micro_Delay(): num=%d, denom=%d, spin count = %d\n", num, denom, numSpins); - - Spin(numSpins); -}