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