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 36extern timer_info gPITTimer; 37extern timer_info gAPICTimer; 38extern timer_info gHPETTimer; 39 40static timer_info *sTimers[] = { 41 &gHPETTimer, 42 &gAPICTimer, 43 &gPITTimer, 44 NULL 45}; 46 47static timer_info *sTimer = NULL; 48 49void 50arch_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 57void 58arch_timer_clear_hardware_timer(void) 59{ 60 TRACE("arch_timer_clear_hardware_timer\n"); 61 sTimer->clear_hardware_timer(); 62} 63 64 65static void 66sort_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 93int 94arch_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