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("arch_timer: " x) 31 #else 32 # define TRACE(x...) ; 33 #endif 34 35 36 extern timer_info gPITTimer; 37 extern timer_info gAPICTimer; 38 extern timer_info gHPETTimer; 39 40 static timer_info *sTimers[] = { 41 &gHPETTimer, 42 &gAPICTimer, 43 &gPITTimer, 44 NULL 45 }; 46 47 static timer_info *sTimer = NULL; 48 49 void 50 arch_timer_set_hardware_timer(bigtime_t timeout) 51 { 52 TRACE("arch_timer_set_hardware_timer: timeout %" B_PRIdBIGTIME "\n", timeout); 53 sTimer->set_hardware_timer(timeout); 54 } 55 56 57 void 58 arch_timer_clear_hardware_timer(void) 59 { 60 TRACE("arch_timer_clear_hardware_timer\n"); 61 sTimer->clear_hardware_timer(); 62 } 63 64 65 static void 66 sort_timers(timer_info *timers[], int numTimers) 67 { 68 timer_info *tempPtr; 69 int max = 0; 70 int i = 0; 71 int j = 0; 72 73 for (i = 0; i < numTimers - 1; i++) { 74 max = i; 75 for (j = i + 1; j < numTimers; j++) { 76 if (timers[j]->get_priority() > timers[max]->get_priority()) 77 max = j; 78 } 79 if (max != i) { 80 tempPtr = timers[max]; 81 timers[max] = timers[i]; 82 timers[i] = tempPtr; 83 } 84 } 85 86 #if 0 87 for (i = 0; i < numTimers; i++) 88 dprintf(" %s: priority %d\n", timers[i]->name, timers[i]->get_priority()); 89 #endif 90 } 91 92 93 int 94 arch_init_timer(kernel_args *args) 95 { 96 // Sort timers by priority 97 sort_timers(sTimers, (sizeof(sTimers) / sizeof(sTimers[0])) - 1); 98 99 timer_info *timer = NULL; 100 cpu_status state = disable_interrupts(); 101 102 for (int i = 0; (timer = sTimers[i]) != NULL; i++) { 103 if (timer->init(args) == B_OK) 104 break; 105 } 106 107 sTimer = timer; 108 109 if (sTimer != NULL) { 110 dprintf("arch_init_timer: using %s timer.\n", sTimer->name); 111 } else { 112 panic("No system timers were found usable.\n"); 113 } 114 115 restore_interrupts(state); 116 117 return 0; 118 } 119 120