xref: /haiku/headers/private/kernel/arch/x86/arch_hpet.h (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
117d39c90SStefano Ceccherini /*
217d39c90SStefano Ceccherini  * Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved.
317d39c90SStefano Ceccherini  * Distributed under the terms of the MIT License.
417d39c90SStefano Ceccherini  */
517d39c90SStefano Ceccherini #ifndef _KERNEL_ARCH_x86_HPET_H
617d39c90SStefano Ceccherini #define _KERNEL_ARCH_x86_HPET_H
717d39c90SStefano Ceccherini 
8*91ee0332SDavid Karoly #include <acpi.h>
917d39c90SStefano Ceccherini 
1017d39c90SStefano Ceccherini /* All masks are 32 bits wide to represent relative bit locations */
1117d39c90SStefano Ceccherini /* Doing it this way is Required since the HPET only supports 32/64-bit aligned reads. */
1217d39c90SStefano Ceccherini 
1317d39c90SStefano Ceccherini /* Global Capability Register Masks */
14ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_REVID			0x00000000000000FFULL
15ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_NUMTIMERS			0x0000000000001F00ULL
16ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_WIDTH			0x0000000000002000ULL
17ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_LEGACY			0x0000000000008000ULL
18ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_VENDOR_ID			0x00000000FFFF0000ULL
19ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_PERIOD			0xFFFFFFFF00000000ULL
2017d39c90SStefano Ceccherini 
2117d39c90SStefano Ceccherini /* Retrieve Global Capabilities */
22ea40a61aSStefano Ceccherini #define HPET_GET_REVID(regs)		((regs)->capabilities & HPET_CAP_MASK_REVID)
23ea40a61aSStefano Ceccherini #define HPET_GET_NUM_TIMERS(regs)	(((regs)->capabilities & HPET_CAP_MASK_NUMTIMERS) >> 8)
24ea40a61aSStefano Ceccherini #define HPET_IS_64BIT(regs)		(((regs)->capabilities & HPET_CAP_MASK_WIDTH) >> 13)
25ea40a61aSStefano Ceccherini #define HPET_IS_LEGACY_CAPABLE(regs)	(((regs)->capabilities & HPET_CAP_MASK_LEGACY) >> 15)
26ea40a61aSStefano Ceccherini #define HPET_GET_VENDOR_ID(regs)	(((regs)->capabilities & HPET_CAP_MASK_VENDOR_ID) >> 16)
27ea40a61aSStefano Ceccherini #define HPET_GET_PERIOD(regs)		(((regs)->capabilities & HPET_CAP_MASK_PERIOD) >> 32)
2817d39c90SStefano Ceccherini 
2917d39c90SStefano Ceccherini /* Global Config Register Masks */
3017d39c90SStefano Ceccherini #define HPET_CONF_MASK_ENABLED			0x00000001
3117d39c90SStefano Ceccherini #define HPET_CONF_MASK_LEGACY			0x00000002
3217d39c90SStefano Ceccherini 
3317d39c90SStefano Ceccherini /* Retrieve Global Configuration */
3417d39c90SStefano Ceccherini #define HPET_IS_ENABLED(regs)		((regs)->config & HPET_CONF_MASK_ENABLED)
3517d39c90SStefano Ceccherini #define HPET_IS_LEGACY(regs)		(((regs)->config & HPET_CONF_MASK_LEGACY) >> 1)
3617d39c90SStefano Ceccherini 
37ea40a61aSStefano Ceccherini /* Timer Configuration and Capabilities*/
38ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_MASK			0xFFFFFFFF00000000ULL
39ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_ROUTE_MASK		0x3e00UL
40ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_ROUTE_SHIFT		9
41ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_TYPE		0x00000002UL
42ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_ENABLE		0x00000004UL
43ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_TYPE			0x00000008UL
44ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_VAL_SET			0x00000040UL
45ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_32MODE			0x00000100UL
46ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_FSB_ENABLE		0x00004000UL
47ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_PER_INT			0x00000010UL
48ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_SIZE			0x00000020UL
49ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_FSB_INT_DEL		0x00008000UL
506e533246SStefano Ceccherini 
51ea40a61aSStefano Ceccherini #define HPET_GET_CAP_TIMER_ROUTE(timer)		(((timer)->config & HPET_CAP_TIMER_MASK) >> 32)
52ea40a61aSStefano Ceccherini #define HPET_GET_CONF_TIMER_INT_ROUTE(timer)	(((timer)->config & HPET_CONF_TIMER_INT_ROUTE_MASK) >> HPET_CONF_TIMER_INT_ROUTE_SHIFT)
536e533246SStefano Ceccherini 
5417d39c90SStefano Ceccherini #define ACPI_HPET_SIGNATURE			"HPET"
5517d39c90SStefano Ceccherini 
5617d39c90SStefano Ceccherini struct hpet_timer {
5717d39c90SStefano Ceccherini 	/* Timer Configuration/Capability bits, Reversed because x86 is LSB */
58ea40a61aSStefano Ceccherini 	volatile uint64 config;
59ea40a61aSStefano Ceccherini 					/* R/W: Each bit represents one allowed interrupt for this timer. */
603cafc2ecSStefano Ceccherini 					/* If interrupt 16 is allowed, bit 16 will be 1. */
61ea40a61aSStefano Ceccherini 	union {
62ea40a61aSStefano Ceccherini 		volatile uint64 comparator64;	/* R/W: Comparator value */
63ea40a61aSStefano Ceccherini 		volatile uint32 comparator32;
64ea40a61aSStefano Ceccherini 	} u0;				/* non-periodic mode: fires once when main counter = this comparator */
6517d39c90SStefano Ceccherini 					/* periodic mode: fires when timer reaches this value, is increased by the original value */
6617d39c90SStefano Ceccherini 
67ea40a61aSStefano Ceccherini 	volatile uint64 fsb_route[2];	/* R/W: FSB Interrupt Route values */
6817d39c90SStefano Ceccherini };
6917d39c90SStefano Ceccherini 
7017d39c90SStefano Ceccherini 
7117d39c90SStefano Ceccherini struct hpet_regs {
72ea40a61aSStefano Ceccherini 	volatile uint64 capabilities;		/* Read Only */
7317d39c90SStefano Ceccherini 
7417d39c90SStefano Ceccherini 	volatile uint64 reserved1;
7517d39c90SStefano Ceccherini 
763cafc2ecSStefano Ceccherini 	volatile uint64 config;			/* R/W: Config Bits */
7717d39c90SStefano Ceccherini 
7817d39c90SStefano Ceccherini 	volatile uint64 reserved2;
7917d39c90SStefano Ceccherini 
8017d39c90SStefano Ceccherini 	/* Interrupt Status bits */
81ea40a61aSStefano Ceccherini 	volatile uint64 interrupt_status;	/* Interrupt Config bits for timers 0-31 */
8217d39c90SStefano Ceccherini 						/* Level Tigger: 0 = off, 1 = set by hardware, timer is active */
8317d39c90SStefano Ceccherini 						/* Edge Trigger: ignored */
8417d39c90SStefano Ceccherini 						/* Writing 0 will not clear these. Must write 1 again. */
85ea40a61aSStefano Ceccherini 	volatile uint64 reserved3[25];
8617d39c90SStefano Ceccherini 
87ea40a61aSStefano Ceccherini 	union {
88ea40a61aSStefano Ceccherini 		volatile uint64 counter64;	/* R/W */
89ea40a61aSStefano Ceccherini 		volatile uint32 counter32;
90ea40a61aSStefano Ceccherini 	} u0;
9117d39c90SStefano Ceccherini 
9217d39c90SStefano Ceccherini 	volatile uint64 reserved4;
9317d39c90SStefano Ceccherini 
94d54e62b2SStefano Ceccherini 	volatile struct hpet_timer timer[1];
9517d39c90SStefano Ceccherini };
9617d39c90SStefano Ceccherini 
9717d39c90SStefano Ceccherini 
984ddb4993SDavid Karoly typedef struct acpi_hpet_addr {
9917d39c90SStefano Ceccherini 	uint8	address_space;
10017d39c90SStefano Ceccherini 	uint8	register_width;
10117d39c90SStefano Ceccherini 	uint8	register_offset;
10217d39c90SStefano Ceccherini 	uint8	reserved;
10317d39c90SStefano Ceccherini 	uint64	address;
1044ddb4993SDavid Karoly } _PACKED acpi_hpet_addr;
1054ddb4993SDavid Karoly 
1064ddb4993SDavid Karoly 
1074ddb4993SDavid Karoly typedef struct acpi_hpet {
1084ddb4993SDavid Karoly 	acpi_descriptor_header	header;	/* "HPET" signature and acpi header */
1094ddb4993SDavid Karoly 	uint8	hw_revision;
1104ddb4993SDavid Karoly 	uint8	comparators : 5;
1114ddb4993SDavid Karoly 	uint8	countersize : 1;
1124ddb4993SDavid Karoly 	uint8	reserved1 : 1;
1134ddb4993SDavid Karoly 	uint8	legacy_capable : 1;
1144ddb4993SDavid Karoly 	uint16	vendor_id;
1154ddb4993SDavid Karoly 	acpi_hpet_addr hpet_address;
11617d39c90SStefano Ceccherini 	uint8	number;
11717d39c90SStefano Ceccherini 	uint16	min_tick;
11817d39c90SStefano Ceccherini } _PACKED acpi_hpet;
11917d39c90SStefano Ceccherini 
12017d39c90SStefano Ceccherini #endif
121