xref: /haiku/src/system/kernel/arch/x86/timers/x86_pit.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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 static bool sPITTimerInitialized = false;
19 
20 struct timer_info gPITTimer = {
21 	"PIT",
22 	&pit_get_prio,
23 	&pit_set_hardware_timer,
24 	&pit_clear_hardware_timer,
25 	&pit_init
26 };
27 
28 
29 static int
30 pit_get_prio(void)
31 {
32 	return 1;
33 }
34 
35 
36 static int32
37 pit_timer_interrupt(void *data)
38 {
39 	return timer_interrupt();
40 }
41 
42 
43 static status_t
44 pit_set_hardware_timer(bigtime_t relativeTimeout)
45 {
46 	uint16 nextEventClocks;
47 
48 	if (relativeTimeout <= 0)
49 		nextEventClocks = 2;
50 	else if (relativeTimeout < PIT_MAX_TIMER_INTERVAL)
51 		nextEventClocks = relativeTimeout * PIT_CLOCK_RATE / 1000000;
52 	else
53 		nextEventClocks = 0xffff;
54 
55 	out8(PIT_SELCH0 | PIT_RWBOTH | PIT_MD_INTON0, PIT_CTRL);
56 	out8(nextEventClocks & 0xff, PIT_CNT0);
57 	out8((nextEventClocks >> 8) & 0xff, PIT_CNT0);
58 
59 	arch_int_enable_io_interrupt(0);
60 	return B_OK;
61 }
62 
63 
64 static status_t
65 pit_clear_hardware_timer(void)
66 {
67 	arch_int_disable_io_interrupt(0);
68 	return B_OK;
69 }
70 
71 
72 static status_t
73 pit_init(struct kernel_args *args)
74 {
75 	if (sPITTimerInitialized) {
76 		return B_OK;
77 	}
78 
79 	install_io_interrupt_handler(0, &pit_timer_interrupt, NULL, 0);
80 	pit_clear_hardware_timer();
81 
82 	sPITTimerInitialized = true;
83 
84 	return B_OK;
85 }
86