2008-08-22 12:15:14 +04:00
|
|
|
/*
|
|
|
|
* Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved.
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
|
|
|
#ifndef _KERNEL_ARCH_x86_HPET_H
|
|
|
|
#define _KERNEL_ARCH_x86_HPET_H
|
|
|
|
|
|
|
|
#include <arch/x86/arch_acpi.h>
|
|
|
|
|
|
|
|
/* All masks are 32 bits wide to represent relative bit locations */
|
|
|
|
/* Doing it this way is Required since the HPET only supports 32/64-bit aligned reads. */
|
|
|
|
|
|
|
|
/* Global Capability Register Masks */
|
2009-09-29 12:36:36 +04:00
|
|
|
#define HPET_CAP_MASK_REVID 0x00000000000000FFULL
|
|
|
|
#define HPET_CAP_MASK_NUMTIMERS 0x0000000000001F00ULL
|
|
|
|
#define HPET_CAP_MASK_WIDTH 0x0000000000002000ULL
|
|
|
|
#define HPET_CAP_MASK_LEGACY 0x0000000000008000ULL
|
|
|
|
#define HPET_CAP_MASK_VENDOR_ID 0x00000000FFFF0000ULL
|
|
|
|
#define HPET_CAP_MASK_PERIOD 0xFFFFFFFF00000000ULL
|
2008-08-22 12:15:14 +04:00
|
|
|
|
|
|
|
/* Retrieve Global Capabilities */
|
2009-09-29 12:36:36 +04:00
|
|
|
#define HPET_GET_REVID(regs) ((regs)->capabilities & HPET_CAP_MASK_REVID)
|
|
|
|
#define HPET_GET_NUM_TIMERS(regs) (((regs)->capabilities & HPET_CAP_MASK_NUMTIMERS) >> 8)
|
|
|
|
#define HPET_IS_64BIT(regs) (((regs)->capabilities & HPET_CAP_MASK_WIDTH) >> 13)
|
|
|
|
#define HPET_IS_LEGACY_CAPABLE(regs) (((regs)->capabilities & HPET_CAP_MASK_LEGACY) >> 15)
|
|
|
|
#define HPET_GET_VENDOR_ID(regs) (((regs)->capabilities & HPET_CAP_MASK_VENDOR_ID) >> 16)
|
|
|
|
#define HPET_GET_PERIOD(regs) (((regs)->capabilities & HPET_CAP_MASK_PERIOD) >> 32)
|
2008-08-22 12:15:14 +04:00
|
|
|
|
|
|
|
/* Global Config Register Masks */
|
|
|
|
#define HPET_CONF_MASK_ENABLED 0x00000001
|
|
|
|
#define HPET_CONF_MASK_LEGACY 0x00000002
|
|
|
|
|
|
|
|
/* Retrieve Global Configuration */
|
|
|
|
#define HPET_IS_ENABLED(regs) ((regs)->config & HPET_CONF_MASK_ENABLED)
|
|
|
|
#define HPET_IS_LEGACY(regs) (((regs)->config & HPET_CONF_MASK_LEGACY) >> 1)
|
|
|
|
|
2009-09-29 12:36:36 +04:00
|
|
|
/* Timer Configuration and Capabilities*/
|
|
|
|
#define HPET_CAP_TIMER_MASK 0xFFFFFFFF00000000ULL
|
|
|
|
#define HPET_CONF_TIMER_INT_ROUTE_MASK 0x3e00UL
|
|
|
|
#define HPET_CONF_TIMER_INT_ROUTE_SHIFT 9
|
|
|
|
#define HPET_CONF_TIMER_INT_TYPE 0x00000002UL
|
|
|
|
#define HPET_CONF_TIMER_INT_ENABLE 0x00000004UL
|
|
|
|
#define HPET_CONF_TIMER_TYPE 0x00000008UL
|
|
|
|
#define HPET_CONF_TIMER_VAL_SET 0x00000040UL
|
|
|
|
#define HPET_CONF_TIMER_32MODE 0x00000100UL
|
|
|
|
#define HPET_CONF_TIMER_FSB_ENABLE 0x00004000UL
|
|
|
|
#define HPET_CAP_TIMER_PER_INT 0x00000010UL
|
|
|
|
#define HPET_CAP_TIMER_SIZE 0x00000020UL
|
|
|
|
#define HPET_CAP_TIMER_FSB_INT_DEL 0x00008000UL
|
|
|
|
|
|
|
|
#define HPET_GET_CAP_TIMER_ROUTE(timer) (((timer)->config & HPET_CAP_TIMER_MASK) >> 32)
|
|
|
|
#define HPET_GET_CONF_TIMER_INT_ROUTE(timer) (((timer)->config & HPET_CONF_TIMER_INT_ROUTE_MASK) >> HPET_CONF_TIMER_INT_ROUTE_SHIFT)
|
2009-09-28 09:10:43 +04:00
|
|
|
|
2008-08-22 12:15:14 +04:00
|
|
|
#define ACPI_HPET_SIGNATURE "HPET"
|
|
|
|
|
|
|
|
struct hpet_timer {
|
2009-09-27 12:50:42 +04:00
|
|
|
/* Timer Configuration/Capability bits, Reversed because x86 is LSB */
|
2009-09-29 12:36:36 +04:00
|
|
|
volatile uint64 config;
|
|
|
|
/* R/W: Each bit represents one allowed interrupt for this timer. */
|
2009-09-27 12:50:42 +04:00
|
|
|
/* If interrupt 16 is allowed, bit 16 will be 1. */
|
2009-09-29 12:36:36 +04:00
|
|
|
union {
|
|
|
|
volatile uint64 comparator64; /* R/W: Comparator value */
|
|
|
|
volatile uint32 comparator32;
|
|
|
|
} u0; /* non-periodic mode: fires once when main counter = this comparator */
|
2008-08-22 12:15:14 +04:00
|
|
|
/* periodic mode: fires when timer reaches this value, is increased by the original value */
|
2009-09-27 12:50:42 +04:00
|
|
|
|
2009-09-29 12:36:36 +04:00
|
|
|
volatile uint64 fsb_route[2]; /* R/W: FSB Interrupt Route values */
|
2008-08-22 12:15:14 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct hpet_regs {
|
2009-09-29 12:36:36 +04:00
|
|
|
volatile uint64 capabilities; /* Read Only */
|
2009-09-25 02:06:02 +04:00
|
|
|
|
2008-08-22 12:15:14 +04:00
|
|
|
volatile uint64 reserved1;
|
|
|
|
|
2009-09-29 12:36:36 +04:00
|
|
|
volatile uint64 config; /* R/W: Config Bits */
|
2008-08-22 12:15:14 +04:00
|
|
|
|
|
|
|
volatile uint64 reserved2;
|
|
|
|
|
|
|
|
/* Interrupt Status bits */
|
2009-09-29 12:36:36 +04:00
|
|
|
volatile uint64 interrupt_status; /* Interrupt Config bits for timers 0-31 */
|
|
|
|
/* Level Tigger: 0 = off, 1 = set by hardware, timer is active */
|
|
|
|
/* Edge Trigger: ignored */
|
|
|
|
/* Writing 0 will not clear these. Must write 1 again. */
|
|
|
|
volatile uint64 reserved3[25];
|
|
|
|
|
|
|
|
union {
|
|
|
|
volatile uint64 counter64; /* R/W */
|
|
|
|
volatile uint32 counter32;
|
|
|
|
} u0;
|
2008-08-22 12:15:14 +04:00
|
|
|
|
|
|
|
volatile uint64 reserved4;
|
|
|
|
|
2009-09-25 09:08:22 +04:00
|
|
|
volatile struct hpet_timer timer[1];
|
2008-08-22 12:15:14 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-01-11 20:01:40 +03:00
|
|
|
typedef struct acpi_hpet_addr {
|
|
|
|
uint8 address_space;
|
|
|
|
uint8 register_width;
|
|
|
|
uint8 register_offset;
|
|
|
|
uint8 reserved;
|
|
|
|
uint64 address;
|
|
|
|
} _PACKED acpi_hpet_addr;
|
|
|
|
|
|
|
|
|
2008-08-22 12:15:14 +04:00
|
|
|
typedef struct acpi_hpet {
|
|
|
|
acpi_descriptor_header header; /* "HPET" signature and acpi header */
|
|
|
|
uint8 hw_revision;
|
2022-01-11 20:01:40 +03:00
|
|
|
uint8 comparators : 5;
|
|
|
|
uint8 countersize : 1;
|
|
|
|
uint8 reserved1 : 1;
|
|
|
|
uint8 legacy_capable : 1;
|
|
|
|
uint16 vendor_id;
|
|
|
|
acpi_hpet_addr hpet_address;
|
2008-08-22 12:15:14 +04:00
|
|
|
uint8 number;
|
|
|
|
uint16 min_tick;
|
|
|
|
} _PACKED acpi_hpet;
|
|
|
|
|
|
|
|
#endif
|