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