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 <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
56struct 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
71struct 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
98typedef 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
107typedef 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