xref: /haiku/headers/private/kernel/arch/x86/arch_hpet.h (revision f75a7bf508f3156d63a14f8fd77c5e0ca4d08c42)
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_ID			0x000000FF
15 #define HPET_CAP_MASK_NUMTIMERS			0x00001F00
16 #define HPET_CAP_MASK_WIDTH			0x00002000
17 #define HPET_CAP_MASK_LEGACY			0x00008000
18 #define HPET_CAP_MASK_VENDOR_ID			0xFFFF0000
19 
20 /* Retrieve Global Capabilities */
21 #define HPET_GET_ID(regs)		((regs)->capability & HPET_CAP_MASK_ID)
22 #define HPET_GET_NUM_TIMERS(regs)	(((regs)->capability & HPET_CAP_MASK_NUMTIMERS) >> 8)
23 #define HPET_IS_64BIT(regs)		(((regs)->capability & HPET_CAP_MASK_WIDTH) >> 13)
24 #define HPET_IS_LEGACY_CAPABLE(regs)	(((regs)->capability & HPET_CAP_MASK_LEGACY) >> 15)
25 #define HPET_GET_VENDOR_ID(regs)	(((regs)->capability & HPET_CAP_MASK_VENDOR_ID) >> 16)
26 
27 /* Global Config Register Masks */
28 #define HPET_CONF_MASK_ENABLED			0x00000001
29 #define HPET_CONF_MASK_LEGACY			0x00000002
30 
31 /* Retrieve Global Configuration */
32 #define HPET_IS_ENABLED(regs)		((regs)->config & HPET_CONF_MASK_ENABLED)
33 #define HPET_IS_LEGACY(regs)		(((regs)->config & HPET_CONF_MASK_LEGACY) >> 1)
34 
35 #define ACPI_HPET_SIGNATURE			"HPET"
36 
37 struct hpet_timer {
38 	/* Timer Configuration/Capability bits, Reversed because x86 is LSB */
39 	volatile uint32 config;
40 	volatile uint32 interrupts;		/* Each bit represents one allowed interrupt for this timer. */
41 					/* Read Only. If interrupt 16 is allowed, bit 16 will be 1. */
42 
43 	volatile uint64 comparator;		/* Comparator value */
44 					/* non-periodic mode: fires once when main counter = this comparator */
45 					/* periodic mode: fires when timer reaches this value, is increased by the original value */
46 
47 	/* FSB Interrupt Route values */
48 	volatile uint32 fsb_value;
49 	volatile uint32 fsb_addr;		/* Where fsb_value should be written */
50 
51 	volatile uint64 reserved;
52 };
53 
54 
55 struct hpet_regs {
56 	/* Capability bits */
57 	volatile uint32 period;
58 	volatile uint32 capability;			/* Capabilities */
59 
60 	volatile uint64 reserved1;
61 
62 	/* Config Bits */
63 	volatile uint64 config;
64 
65 	volatile uint64 reserved2;
66 
67 	/* Interrupt Status bits */
68 	volatile uint64 timer_interrupts;	/* Interrupt Config bits for timers 0-31 */
69 					/* Level Tigger: 0 = off, 1 = set by hardware, timer is active */
70 					/* Edge Trigger: ignored */
71 					/* Writing 0 will not clear these. Must write 1 again. */
72 
73 	volatile uint8 reserved3[200];
74 
75 	volatile uint64 counter;
76 
77 	volatile uint64 reserved4;
78 
79 	volatile struct hpet_timer timer0;
80 	volatile struct hpet_timer timer1;
81 	volatile struct hpet_timer timer2;
82 };
83 
84 
85 typedef struct acpi_hpet {
86 	acpi_descriptor_header	header;	/* "HPET" signature and acpi header */
87 	uint16	vendor_id;
88 	uint8	legacy_capable : 1;
89 	uint8	reserved1 : 1;
90 	uint8	countersize : 1;
91 	uint8	comparators : 5;
92 	uint8	hw_revision;
93 	struct hpet_addr {
94 		uint8	address_space;
95 		uint8	register_width;
96 		uint8	register_offset;
97 		uint8	reserved;
98 		uint64	address;
99 	} hpet_address;
100 	uint8	number;
101 	uint16	min_tick;
102 } _PACKED acpi_hpet;
103 
104 #endif
105