1 /* 2 * Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved. 3 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 * 6 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 10 #include <timer.h> 11 #include <arch/x86/timer.h> 12 13 #include <arch/int.h> 14 #include <arch/cpu.h> 15 16 #include "pit.h" 17 18 19 //#define TRACE_PIT 20 #ifdef TRACE_PIT 21 # define TRACE(x...) dprintf("pit: " x) 22 #else 23 # define TRACE(x...) ; 24 #endif 25 26 27 static bool sPITTimerInitialized = false; 28 29 struct timer_info gPITTimer = { 30 "PIT", 31 &pit_get_prio, 32 &pit_set_hardware_timer, 33 &pit_clear_hardware_timer, 34 &pit_init 35 }; 36 37 38 static int 39 pit_get_prio(void) 40 { 41 return 1; 42 } 43 44 45 static int32 46 pit_timer_interrupt(void *data) 47 { 48 return timer_interrupt(); 49 } 50 51 52 static status_t 53 pit_set_hardware_timer(bigtime_t relativeTimeout) 54 { 55 uint16 nextEventClocks; 56 57 if (relativeTimeout <= 0) 58 nextEventClocks = 2; 59 else if (relativeTimeout < PIT_MAX_TIMER_INTERVAL) 60 nextEventClocks = relativeTimeout * PIT_CLOCK_RATE / 1000000; 61 else 62 nextEventClocks = 0xffff; 63 64 out8(PIT_SELCH0 | PIT_RWBOTH | PIT_MD_INTON0, PIT_CTRL); 65 out8(nextEventClocks & 0xff, PIT_CNT0); 66 out8((nextEventClocks >> 8) & 0xff, PIT_CNT0); 67 68 arch_int_enable_io_interrupt(0); 69 return B_OK; 70 } 71 72 73 static status_t 74 pit_clear_hardware_timer(void) 75 { 76 arch_int_disable_io_interrupt(0); 77 return B_OK; 78 } 79 80 81 static status_t 82 pit_init(struct kernel_args *args) 83 { 84 if (sPITTimerInitialized) { 85 TRACE("timer is already initialized"); 86 return B_OK; 87 } 88 89 install_io_interrupt_handler(0, &pit_timer_interrupt, NULL, 0); 90 pit_clear_hardware_timer(); 91 92 sPITTimerInitialized = true; 93 TRACE("timer initialized"); 94 95 return B_OK; 96 } 97