xref: /haiku/src/add-ons/kernel/drivers/timer/hpet.h (revision 7749d0bb0c358a3279b1b9cc76d8376e900130a5)
1 /*
2  * Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _KERNEL_ARCH_x86_HPET_H
6 #define _KERNEL_ARCH_x86_HPET_H
7 
8 #include <OS.h>
9 #include "arch_acpi.h"
10 
11 /* All masks are 32 bits wide to represent relative bit locations */
12 /* Doing it this way is Required since the HPET only supports 32/64-bit aligned reads. */
13 
14 /* Global Capability Register Masks */
15 #define HPET_CAP_MASK_REVID				0x00000000000000FFULL
16 #define HPET_CAP_MASK_NUMTIMERS			0x0000000000001F00ULL
17 #define HPET_CAP_MASK_WIDTH				0x0000000000002000ULL
18 #define HPET_CAP_MASK_LEGACY			0x0000000000008000ULL
19 #define HPET_CAP_MASK_VENDOR_ID			0x00000000FFFF0000ULL
20 #define HPET_CAP_MASK_PERIOD			0xFFFFFFFF00000000ULL
21 
22 /* Retrieve Global Capabilities */
23 #define HPET_GET_REVID(regs)			((regs)->capabilities & HPET_CAP_MASK_REVID)
24 #define HPET_GET_NUM_TIMERS(regs)		(((regs)->capabilities & HPET_CAP_MASK_NUMTIMERS) >> 8)
25 #define HPET_IS_64BIT(regs)				(((regs)->capabilities & HPET_CAP_MASK_WIDTH) >> 13)
26 #define HPET_IS_LEGACY_CAPABLE(regs)	(((regs)->capabilities & HPET_CAP_MASK_LEGACY) >> 15)
27 #define HPET_GET_VENDOR_ID(regs)		(((regs)->capabilities & HPET_CAP_MASK_VENDOR_ID) >> 16)
28 #define HPET_GET_PERIOD(regs)			(((regs)->capabilities & HPET_CAP_MASK_PERIOD) >> 32)
29 
30 /* Global Config Register Masks */
31 #define HPET_CONF_MASK_ENABLED			0x00000001
32 #define HPET_CONF_MASK_LEGACY			0x00000002
33 
34 /* Retrieve Global Configuration */
35 #define HPET_IS_ENABLED(regs)		((regs)->config & HPET_CONF_MASK_ENABLED)
36 #define HPET_IS_LEGACY(regs)		(((regs)->config & HPET_CONF_MASK_LEGACY) >> 1)
37 
38 /* Timer Configuration and Capabilities*/
39 #define HPET_CAP_TIMER_MASK			0xFFFFFFFF00000000ULL
40 #define HPET_CAP_TIMER_PER_INT		0x00000010UL
41 #define HPET_CAP_TIMER_SIZE			0x00000020UL
42 #define HPET_CAP_TIMER_FSB_INT_DEL	0x00008000UL
43 #define HPET_GET_CAP_TIMER_ROUTE(timer)		(((timer)->config & HPET_CAP_TIMER_MASK) >> 32)
44 
45 #define HPET_CONF_TIMER_INT_ROUTE_MASK		0x3e00UL
46 #define HPET_CONF_TIMER_INT_ROUTE_SHIFT		9
47 #define HPET_CONF_TIMER_INT_TYPE			0x00000002UL
48 #define HPET_CONF_TIMER_INT_ENABLE			0x00000004UL
49 #define HPET_CONF_TIMER_TYPE				0x00000008UL
50 #define HPET_CONF_TIMER_VAL_SET				0x00000040UL
51 #define HPET_CONF_TIMER_32MODE				0x00000100UL
52 #define HPET_CONF_TIMER_FSB_ENABLE			0x00004000UL
53 #define HPET_GET_CONF_TIMER_INT_ROUTE(timer)	(((timer)->config & HPET_CONF_TIMER_INT_ROUTE_MASK) >> HPET_CONF_TIMER_INT_ROUTE_SHIFT)
54 #define HPET_GET_CONF_TIMER_INT_IS_LEVEL(timer)	(((timer)->config & HPET_CONF_TIMER_INT_TYPE))
55 
56 #define ACPI_HPET_SIGNATURE			"HPET"
57 
58 struct hpet_timer {
59 	/* Timer Configuration/Capability bits, Reversed because x86 is LSB */
60 	volatile uint64 config;
61 					/* R/W: Each bit represents one allowed interrupt for this timer. */
62 					/* If interrupt 16 is allowed, bit 16 will be 1. */
63 	union {
64 		volatile uint64 comparator64;	/* R/W: Comparator value */
65 		volatile uint32 comparator32;
66 	} u0;				/* non-periodic mode: fires once when main counter = this comparator */
67 					/* periodic mode: fires when timer reaches this value, is increased by the original value */
68 
69 	volatile uint64 fsb_route[2];	/* R/W: FSB Interrupt Route values */
70 };
71 
72 
73 struct hpet_regs {
74 	volatile uint64 capabilities;		/* Read Only */
75 
76 	volatile uint64 reserved1;
77 
78 	volatile uint64 config;			/* R/W: Config Bits */
79 
80 	volatile uint64 reserved2;
81 
82 	/* Interrupt Status bits */
83 	volatile uint64 interrupt_status;	/* Interrupt Config bits for timers 0-31 */
84 						/* Level Tigger: 0 = off, 1 = set by hardware, timer is active */
85 						/* Edge Trigger: ignored */
86 						/* Writing 0 will not clear these. Must write 1 again. */
87 	uint64 reserved3[25];
88 
89 	union {
90 		volatile uint64 counter64;	/* R/W */
91 		volatile uint32 counter32;
92 	} u0;
93 
94 	uint64 reserved4;
95 
96 	struct hpet_timer timer[1];
97 };
98 
99 
100 typedef struct acpi_hpet {
101 	acpi_descriptor_header	header;	/* "HPET" signature and acpi header */
102 	uint16	vendor_id;
103 	uint8	legacy_capable : 1;
104 	uint8	reserved1 : 1;
105 	uint8	countersize : 1;
106 	uint8	comparators : 5;
107 	uint8	hw_revision;
108 	struct hpet_addr {
109 		uint8	address_space;
110 		uint8	register_width;
111 		uint8	register_offset;
112 		uint8	reserved;
113 		uint64	address;
114 	} hpet_address;
115 	uint8	number;
116 	uint16	min_tick;
117 } _PACKED acpi_hpet;
118 
119 #endif
120