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
pit_get_prio(void)39 pit_get_prio(void)
40 {
41 return 1;
42 }
43
44
45 static int32
pit_timer_interrupt(void * data)46 pit_timer_interrupt(void *data)
47 {
48 return timer_interrupt();
49 }
50
51
52 static status_t
pit_set_hardware_timer(bigtime_t relativeTimeout)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
pit_clear_hardware_timer(void)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
pit_init(struct kernel_args * args)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