2 * Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 #ifndef _KERNEL_ARCH_x86_HPET_H
6 #define _KERNEL_ARCH_x86_HPET_H
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. */
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
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)
30 /* Global Config Register Masks */
31 #define HPET_CONF_MASK_ENABLED 0x00000001
32 #define HPET_CONF_MASK_LEGACY 0x00000002
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)
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)
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))
56 #define ACPI_HPET_SIGNATURE "HPET"
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. */
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 */
69 volatile uint64 fsb_route
[2]; /* R/W: FSB Interrupt Route values */
74 volatile uint64 capabilities
; /* Read Only */
76 volatile uint64 reserved1
;
78 volatile uint64 config
; /* R/W: Config Bits */
80 volatile uint64 reserved2
;
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. */
90 volatile uint64 counter64
; /* R/W */
91 volatile uint32 counter32
;
96 struct hpet_timer timer
[1];
100 typedef struct acpi_hpet
{
101 acpi_descriptor_header header
; /* "HPET" signature and acpi header */
103 uint8 legacy_capable
: 1;
105 uint8 countersize
: 1;
106 uint8 comparators
: 5;
110 uint8 register_width
;
111 uint8 register_offset
;