1 /* 2 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8 9 10 #include <boot/stage2.h> 11 #include <kernel.h> 12 13 #include <arch/int.h> 14 #include <arch/cpu.h> 15 16 #include <console.h> 17 #include <debug.h> 18 #include <timer.h> 19 #include <int.h> 20 #include <safemode.h> 21 22 #include <arch/timer.h> 23 24 #include <arch/x86/smp_priv.h> 25 #include <arch/x86/timer.h> 26 27 28 //#define TRACE_TIMER 29 #ifdef TRACE_TIMER 30 # define TRACE(x) dprintf x 31 #else 32 # define TRACE(x) ; 33 #endif 34 35 extern timer_info gPITTimer; 36 extern timer_info gAPICTimer; 37 extern timer_info gHPETTimer; 38 39 static timer_info *sTimers[] = { 40 &gHPETTimer, 41 &gAPICTimer, 42 &gPITTimer, 43 NULL 44 }; 45 46 static timer_info *sTimer = NULL; 47 48 void 49 arch_timer_set_hardware_timer(bigtime_t timeout) 50 { 51 TRACE(("arch_timer_set_hardware_timer: timeout %lld\n", timeout)); 52 sTimer->set_hardware_timer(timeout); 53 } 54 55 56 void 57 arch_timer_clear_hardware_timer(void) 58 { 59 TRACE(("arch_timer_clear_hardware_timer\n")); 60 sTimer->clear_hardware_timer(); 61 } 62 63 64 static void 65 sort_timers(timer_info *timers[], int numTimers) 66 { 67 timer_info *tempPtr; 68 int max = 0; 69 int i = 0; 70 int j = 0; 71 72 for (i = 0; i < numTimers - 1; i++) { 73 max = i; 74 for (j = i + 1; j < numTimers; j++) { 75 if (timers[j]->get_priority() > timers[max]->get_priority()) 76 max = j; 77 } 78 if (max != i) { 79 tempPtr = timers[max]; 80 timers[max] = timers[i]; 81 timers[i] = tempPtr; 82 } 83 } 84 85 #if 0 86 for (i = 0; i < numTimers; i++) 87 dprintf(" %s: priority %d\n", timers[i]->name, timers[i]->get_priority()); 88 #endif 89 } 90 91 92 int 93 arch_init_timer(kernel_args *args) 94 { 95 // Sort timers by priority 96 sort_timers(sTimers, (sizeof(sTimers) / sizeof(sTimers[0])) - 1); 97 98 timer_info *timer = NULL; 99 cpu_status state = disable_interrupts(); 100 101 for (int i = 0; (timer = sTimers[i]) != NULL; i++) { 102 if (timer->init(args) == B_OK) 103 break; 104 } 105 106 sTimer = timer; 107 108 if (sTimer != NULL) { 109 dprintf("arch_init_timer: using %s timer.\n", sTimer->name); 110 } else { 111 panic("No system timers were found usable.\n"); 112 } 113 114 restore_interrupts(state); 115 116 return 0; 117 } 118 119