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