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 */ 14cd1352feSStefano Ceccherini #define HPET_CAP_MASK_ID 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 */ 2117d39c90SStefano Ceccherini #define HPET_GET_ID(regs) ((regs)->capability & HPET_CAP_MASK_ID) 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 3517d39c90SStefano Ceccherini #define ACPI_HPET_SIGNATURE "HPET" 3617d39c90SStefano Ceccherini 3717d39c90SStefano Ceccherini struct hpet_timer { 3817d39c90SStefano Ceccherini /* Timer Configuration/Capability bits, Reversed because x86 is LSB */ 3917d39c90SStefano Ceccherini volatile uint32 config; 4017d39c90SStefano Ceccherini volatile uint32 interrupts; /* Each bit represents one allowed interrupt for this timer. */ 4117d39c90SStefano Ceccherini /* Read Only. If interrupt 16 is allowed, bit 16 will be 1. */ 4217d39c90SStefano Ceccherini 4317d39c90SStefano Ceccherini volatile uint64 comparator; /* Comparator value */ 4417d39c90SStefano Ceccherini /* non-periodic mode: fires once when main counter = this comparator */ 4517d39c90SStefano Ceccherini /* periodic mode: fires when timer reaches this value, is increased by the original value */ 4617d39c90SStefano Ceccherini 4717d39c90SStefano Ceccherini /* FSB Interrupt Route values */ 4817d39c90SStefano Ceccherini volatile uint32 fsb_value; 4917d39c90SStefano Ceccherini volatile uint32 fsb_addr; /* Where fsb_value should be written */ 5017d39c90SStefano Ceccherini 5117d39c90SStefano Ceccherini volatile uint64 reserved; 5217d39c90SStefano Ceccherini }; 5317d39c90SStefano Ceccherini 5417d39c90SStefano Ceccherini 5517d39c90SStefano Ceccherini struct hpet_regs { 5617d39c90SStefano Ceccherini /* Capability bits */ 5717d39c90SStefano Ceccherini volatile uint32 capability; /* Capabilities */ 58cd1352feSStefano Ceccherini volatile uint32 period; 5917d39c90SStefano Ceccherini 6017d39c90SStefano Ceccherini volatile uint64 reserved1; 6117d39c90SStefano Ceccherini 6217d39c90SStefano Ceccherini /* Config Bits */ 6317d39c90SStefano Ceccherini volatile uint64 config; 6417d39c90SStefano Ceccherini 6517d39c90SStefano Ceccherini volatile uint64 reserved2; 6617d39c90SStefano Ceccherini 6717d39c90SStefano Ceccherini /* Interrupt Status bits */ 6817d39c90SStefano Ceccherini volatile uint64 timer_interrupts; /* Interrupt Config bits for timers 0-31 */ 6917d39c90SStefano Ceccherini /* Level Tigger: 0 = off, 1 = set by hardware, timer is active */ 7017d39c90SStefano Ceccherini /* Edge Trigger: ignored */ 7117d39c90SStefano Ceccherini /* Writing 0 will not clear these. Must write 1 again. */ 7217d39c90SStefano Ceccherini 7317d39c90SStefano Ceccherini volatile uint8 reserved3[200]; 7417d39c90SStefano Ceccherini 7517d39c90SStefano Ceccherini volatile uint64 counter; 7617d39c90SStefano Ceccherini 7717d39c90SStefano Ceccherini volatile uint64 reserved4; 7817d39c90SStefano Ceccherini 79*d54e62b2SStefano Ceccherini volatile struct hpet_timer timer[1]; 8017d39c90SStefano Ceccherini }; 8117d39c90SStefano Ceccherini 8217d39c90SStefano Ceccherini 8317d39c90SStefano Ceccherini typedef struct acpi_hpet { 8417d39c90SStefano Ceccherini acpi_descriptor_header header; /* "HPET" signature and acpi header */ 8517d39c90SStefano Ceccherini uint16 vendor_id; 8617d39c90SStefano Ceccherini uint8 legacy_capable : 1; 8717d39c90SStefano Ceccherini uint8 reserved1 : 1; 8817d39c90SStefano Ceccherini uint8 countersize : 1; 8917d39c90SStefano Ceccherini uint8 comparators : 5; 9017d39c90SStefano Ceccherini uint8 hw_revision; 9117d39c90SStefano Ceccherini struct hpet_addr { 9217d39c90SStefano Ceccherini uint8 address_space; 9317d39c90SStefano Ceccherini uint8 register_width; 9417d39c90SStefano Ceccherini uint8 register_offset; 9517d39c90SStefano Ceccherini uint8 reserved; 9617d39c90SStefano Ceccherini uint64 address; 9717d39c90SStefano Ceccherini } hpet_address; 9817d39c90SStefano Ceccherini uint8 number; 9917d39c90SStefano Ceccherini uint16 min_tick; 10017d39c90SStefano Ceccherini } _PACKED acpi_hpet; 10117d39c90SStefano Ceccherini 10217d39c90SStefano Ceccherini #endif 103