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 */ 14*ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_REVID 0x00000000000000FFULL 15*ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_NUMTIMERS 0x0000000000001F00ULL 16*ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_WIDTH 0x0000000000002000ULL 17*ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_LEGACY 0x0000000000008000ULL 18*ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_VENDOR_ID 0x00000000FFFF0000ULL 19*ea40a61aSStefano Ceccherini #define HPET_CAP_MASK_PERIOD 0xFFFFFFFF00000000ULL 2017d39c90SStefano Ceccherini 2117d39c90SStefano Ceccherini /* Retrieve Global Capabilities */ 22*ea40a61aSStefano Ceccherini #define HPET_GET_REVID(regs) ((regs)->capabilities & HPET_CAP_MASK_REVID) 23*ea40a61aSStefano Ceccherini #define HPET_GET_NUM_TIMERS(regs) (((regs)->capabilities & HPET_CAP_MASK_NUMTIMERS) >> 8) 24*ea40a61aSStefano Ceccherini #define HPET_IS_64BIT(regs) (((regs)->capabilities & HPET_CAP_MASK_WIDTH) >> 13) 25*ea40a61aSStefano Ceccherini #define HPET_IS_LEGACY_CAPABLE(regs) (((regs)->capabilities & HPET_CAP_MASK_LEGACY) >> 15) 26*ea40a61aSStefano Ceccherini #define HPET_GET_VENDOR_ID(regs) (((regs)->capabilities & HPET_CAP_MASK_VENDOR_ID) >> 16) 27*ea40a61aSStefano 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 37*ea40a61aSStefano Ceccherini /* Timer Configuration and Capabilities*/ 38*ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_MASK 0xFFFFFFFF00000000ULL 39*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_ROUTE_MASK 0x3e00UL 40*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_ROUTE_SHIFT 9 41*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_TYPE 0x00000002UL 42*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_INT_ENABLE 0x00000004UL 43*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_TYPE 0x00000008UL 44*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_VAL_SET 0x00000040UL 45*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_32MODE 0x00000100UL 46*ea40a61aSStefano Ceccherini #define HPET_CONF_TIMER_FSB_ENABLE 0x00004000UL 47*ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_PER_INT 0x00000010UL 48*ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_SIZE 0x00000020UL 49*ea40a61aSStefano Ceccherini #define HPET_CAP_TIMER_FSB_INT_DEL 0x00008000UL 506e533246SStefano Ceccherini 51*ea40a61aSStefano Ceccherini #define HPET_GET_CAP_TIMER_ROUTE(timer) (((timer)->config & HPET_CAP_TIMER_MASK) >> 32) 52*ea40a61aSStefano 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 */ 58*ea40a61aSStefano Ceccherini volatile uint64 config; 59*ea40a61aSStefano Ceccherini /* R/W: Each bit represents one allowed interrupt for this timer. */ 603cafc2ecSStefano Ceccherini /* If interrupt 16 is allowed, bit 16 will be 1. */ 61*ea40a61aSStefano Ceccherini union { 62*ea40a61aSStefano Ceccherini volatile uint64 comparator64; /* R/W: Comparator value */ 63*ea40a61aSStefano Ceccherini volatile uint32 comparator32; 64*ea40a61aSStefano 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 67*ea40a61aSStefano Ceccherini volatile uint64 fsb_route[2]; /* R/W: FSB Interrupt Route values */ 6817d39c90SStefano Ceccherini }; 6917d39c90SStefano Ceccherini 7017d39c90SStefano Ceccherini 7117d39c90SStefano Ceccherini struct hpet_regs { 72*ea40a61aSStefano 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 */ 81*ea40a61aSStefano 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. */ 85*ea40a61aSStefano Ceccherini volatile uint64 reserved3[25]; 8617d39c90SStefano Ceccherini 87*ea40a61aSStefano Ceccherini union { 88*ea40a61aSStefano Ceccherini volatile uint64 counter64; /* R/W */ 89*ea40a61aSStefano Ceccherini volatile uint32 counter32; 90*ea40a61aSStefano 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 9817d39c90SStefano Ceccherini typedef struct acpi_hpet { 9917d39c90SStefano Ceccherini acpi_descriptor_header header; /* "HPET" signature and acpi header */ 10017d39c90SStefano Ceccherini uint16 vendor_id; 10117d39c90SStefano Ceccherini uint8 legacy_capable : 1; 10217d39c90SStefano Ceccherini uint8 reserved1 : 1; 10317d39c90SStefano Ceccherini uint8 countersize : 1; 10417d39c90SStefano Ceccherini uint8 comparators : 5; 10517d39c90SStefano Ceccherini uint8 hw_revision; 10617d39c90SStefano Ceccherini struct hpet_addr { 10717d39c90SStefano Ceccherini uint8 address_space; 10817d39c90SStefano Ceccherini uint8 register_width; 10917d39c90SStefano Ceccherini uint8 register_offset; 11017d39c90SStefano Ceccherini uint8 reserved; 11117d39c90SStefano Ceccherini uint64 address; 11217d39c90SStefano Ceccherini } hpet_address; 11317d39c90SStefano Ceccherini uint8 number; 11417d39c90SStefano Ceccherini uint16 min_tick; 11517d39c90SStefano Ceccherini } _PACKED acpi_hpet; 11617d39c90SStefano Ceccherini 11717d39c90SStefano Ceccherini #endif 118