xref: /haiku/headers/private/kernel/arch/x86/arch_hpet.h (revision 6e533246630ad86abf8b8c38c46ccd25d6515956)
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 
817d39c90SStefano Ceccherini #include <arch/x86/arch_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 */
143cafc2ecSStefano Ceccherini #define HPET_CAP_MASK_REVID			0x000000FFL
15cd1352feSStefano Ceccherini #define HPET_CAP_MASK_NUMTIMERS			0x00001F00L
16cd1352feSStefano Ceccherini #define HPET_CAP_MASK_WIDTH			0x00002000L
17cd1352feSStefano Ceccherini #define HPET_CAP_MASK_LEGACY			0x00008000L
18cd1352feSStefano Ceccherini #define HPET_CAP_MASK_VENDOR_ID			0xFFFF0000L
1917d39c90SStefano Ceccherini 
2017d39c90SStefano Ceccherini /* Retrieve Global Capabilities */
213cafc2ecSStefano Ceccherini #define HPET_GET_REVID(regs)		((regs)->capability & HPET_CAP_MASK_REVID)
2217d39c90SStefano Ceccherini #define HPET_GET_NUM_TIMERS(regs)	(((regs)->capability & HPET_CAP_MASK_NUMTIMERS) >> 8)
2317d39c90SStefano Ceccherini #define HPET_IS_64BIT(regs)		(((regs)->capability & HPET_CAP_MASK_WIDTH) >> 13)
2417d39c90SStefano Ceccherini #define HPET_IS_LEGACY_CAPABLE(regs)	(((regs)->capability & HPET_CAP_MASK_LEGACY) >> 15)
2517d39c90SStefano Ceccherini #define HPET_GET_VENDOR_ID(regs)	(((regs)->capability & HPET_CAP_MASK_VENDOR_ID) >> 16)
2617d39c90SStefano Ceccherini 
2717d39c90SStefano Ceccherini /* Global Config Register Masks */
2817d39c90SStefano Ceccherini #define HPET_CONF_MASK_ENABLED			0x00000001
2917d39c90SStefano Ceccherini #define HPET_CONF_MASK_LEGACY			0x00000002
3017d39c90SStefano Ceccherini 
3117d39c90SStefano Ceccherini /* Retrieve Global Configuration */
3217d39c90SStefano Ceccherini #define HPET_IS_ENABLED(regs)		((regs)->config & HPET_CONF_MASK_ENABLED)
3317d39c90SStefano Ceccherini #define HPET_IS_LEGACY(regs)		(((regs)->config & HPET_CONF_MASK_LEGACY) >> 1)
3417d39c90SStefano Ceccherini 
35*6e533246SStefano Ceccherini /* Timer Configuration */
36*6e533246SStefano Ceccherini #define HPET_TIMER_INT_ENB_CNF			0x00000004
37*6e533246SStefano Ceccherini #define HPET_TIMER_TYPE_CNF			0x00000008
38*6e533246SStefano Ceccherini #define HPET_TIMER_PER_INT_CAP			0x00000010
39*6e533246SStefano Ceccherini #define HPET_TIMER_SIZE_CAP			0x00000020
40*6e533246SStefano Ceccherini #define HPET_TIMER_VAL_SET_CNF			0x00000040
41*6e533246SStefano Ceccherini #define HPET_TIMER_32MODE_CNF			0x00000100
42*6e533246SStefano Ceccherini #define HPET_TIMER_TN_FSB_EN_CNF		0x00004000
43*6e533246SStefano Ceccherini #define HPET_TIMER_TN_FSB_INT_DEL_CAP		0x00008000
44*6e533246SStefano Ceccherini 
45*6e533246SStefano Ceccherini 
4617d39c90SStefano Ceccherini #define ACPI_HPET_SIGNATURE			"HPET"
4717d39c90SStefano Ceccherini 
4817d39c90SStefano Ceccherini struct hpet_timer {
4917d39c90SStefano Ceccherini 	/* Timer Configuration/Capability bits, Reversed because x86 is LSB */
5017d39c90SStefano Ceccherini 	volatile uint32 config;
513cafc2ecSStefano Ceccherini 	volatile uint32 interrupts;	/* R/W: Each bit represents one allowed interrupt for this timer. */
523cafc2ecSStefano Ceccherini 					/* If interrupt 16 is allowed, bit 16 will be 1. */
5317d39c90SStefano Ceccherini 
543cafc2ecSStefano Ceccherini 	volatile uint64 comparator;	/* R/W: Comparator value */
5517d39c90SStefano Ceccherini 					/* non-periodic mode: fires once when main counter = this comparator */
5617d39c90SStefano Ceccherini 					/* periodic mode: fires when timer reaches this value, is increased by the original value */
5717d39c90SStefano Ceccherini 
583cafc2ecSStefano Ceccherini 
593cafc2ecSStefano Ceccherini 	volatile uint32 fsb_value;	/* R/W: FSB Interrupt Route values */
603cafc2ecSStefano Ceccherini 	volatile uint32 fsb_addr;	/* R/W: Where fsb_value should be written */
6117d39c90SStefano Ceccherini 
6217d39c90SStefano Ceccherini 	volatile uint64 reserved;
6317d39c90SStefano Ceccherini };
6417d39c90SStefano Ceccherini 
6517d39c90SStefano Ceccherini 
6617d39c90SStefano Ceccherini struct hpet_regs {
6717d39c90SStefano Ceccherini 	/* Capability bits */
683cafc2ecSStefano Ceccherini 	volatile uint32 capability;	/* Read Only: Capabilities */
693cafc2ecSStefano Ceccherini 	volatile uint32 period;		/* Read Only: Period */
7017d39c90SStefano Ceccherini 
7117d39c90SStefano Ceccherini 	volatile uint64 reserved1;
7217d39c90SStefano Ceccherini 
733cafc2ecSStefano Ceccherini 	volatile uint64 config;		/* R/W: Config Bits */
7417d39c90SStefano Ceccherini 
7517d39c90SStefano Ceccherini 	volatile uint64 reserved2;
7617d39c90SStefano Ceccherini 
7717d39c90SStefano Ceccherini 	/* Interrupt Status bits */
7817d39c90SStefano Ceccherini 	volatile uint64 timer_interrupts;	/* Interrupt Config bits for timers 0-31 */
7917d39c90SStefano Ceccherini 					/* Level Tigger: 0 = off, 1 = set by hardware, timer is active */
8017d39c90SStefano Ceccherini 					/* Edge Trigger: ignored */
8117d39c90SStefano Ceccherini 					/* Writing 0 will not clear these. Must write 1 again. */
8217d39c90SStefano Ceccherini 
8317d39c90SStefano Ceccherini 	volatile uint8 reserved3[200];
8417d39c90SStefano Ceccherini 
853cafc2ecSStefano Ceccherini 	volatile uint64 counter;	/* R/W */
8617d39c90SStefano Ceccherini 
8717d39c90SStefano Ceccherini 	volatile uint64 reserved4;
8817d39c90SStefano Ceccherini 
89d54e62b2SStefano Ceccherini 	volatile struct hpet_timer timer[1];
9017d39c90SStefano Ceccherini };
9117d39c90SStefano Ceccherini 
9217d39c90SStefano Ceccherini 
9317d39c90SStefano Ceccherini typedef struct acpi_hpet {
9417d39c90SStefano Ceccherini 	acpi_descriptor_header	header;	/* "HPET" signature and acpi header */
9517d39c90SStefano Ceccherini 	uint16	vendor_id;
9617d39c90SStefano Ceccherini 	uint8	legacy_capable : 1;
9717d39c90SStefano Ceccherini 	uint8	reserved1 : 1;
9817d39c90SStefano Ceccherini 	uint8	countersize : 1;
9917d39c90SStefano Ceccherini 	uint8	comparators : 5;
10017d39c90SStefano Ceccherini 	uint8	hw_revision;
10117d39c90SStefano Ceccherini 	struct hpet_addr {
10217d39c90SStefano Ceccherini 		uint8	address_space;
10317d39c90SStefano Ceccherini 		uint8	register_width;
10417d39c90SStefano Ceccherini 		uint8	register_offset;
10517d39c90SStefano Ceccherini 		uint8	reserved;
10617d39c90SStefano Ceccherini 		uint64	address;
10717d39c90SStefano Ceccherini 	} hpet_address;
10817d39c90SStefano Ceccherini 	uint8	number;
10917d39c90SStefano Ceccherini 	uint16	min_tick;
11017d39c90SStefano Ceccherini } _PACKED acpi_hpet;
11117d39c90SStefano Ceccherini 
11217d39c90SStefano Ceccherini #endif
113