1 /* 2 * Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _KERNEL_ARCH_x86_HPET_H 6 #define _KERNEL_ARCH_x86_HPET_H 7 8 #include <arch/x86/arch_acpi.h> 9 10 /* All masks are 32 bits wide to represent relative bit locations */ 11 /* Doing it this way is Required since the HPET only supports 32/64-bit aligned reads. */ 12 13 /* Global Capability Register Masks */ 14 #define HPET_CAP_MASK_ID 0x000000FF 15 #define HPET_CAP_MASK_NUMTIMERS 0x00001F00 16 #define HPET_CAP_MASK_WIDTH 0x00002000 17 #define HPET_CAP_MASK_LEGACY 0x00008000 18 #define HPET_CAP_MASK_VENDOR_ID 0xFFFF0000 19 20 /* Retrieve Global Capabilities */ 21 #define HPET_GET_ID(regs) ((regs)->capability & HPET_CAP_MASK_ID) 22 #define HPET_GET_NUM_TIMERS(regs) (((regs)->capability & HPET_CAP_MASK_NUMTIMERS) >> 8) 23 #define HPET_IS_64BIT(regs) (((regs)->capability & HPET_CAP_MASK_WIDTH) >> 13) 24 #define HPET_IS_LEGACY_CAPABLE(regs) (((regs)->capability & HPET_CAP_MASK_LEGACY) >> 15) 25 #define HPET_GET_VENDOR_ID(regs) (((regs)->capability & HPET_CAP_MASK_VENDOR_ID) >> 16) 26 27 /* Global Config Register Masks */ 28 #define HPET_CONF_MASK_ENABLED 0x00000001 29 #define HPET_CONF_MASK_LEGACY 0x00000002 30 31 /* Retrieve Global Configuration */ 32 #define HPET_IS_ENABLED(regs) ((regs)->config & HPET_CONF_MASK_ENABLED) 33 #define HPET_IS_LEGACY(regs) (((regs)->config & HPET_CONF_MASK_LEGACY) >> 1) 34 35 #define ACPI_HPET_SIGNATURE "HPET" 36 37 struct hpet_timer { 38 /* Timer Configuration/Capability bits, Reversed because x86 is LSB */ 39 volatile uint32 config; 40 volatile uint32 interrupts; /* Each bit represents one allowed interrupt for this timer. */ 41 /* Read Only. If interrupt 16 is allowed, bit 16 will be 1. */ 42 43 volatile uint64 comparator; /* Comparator value */ 44 /* non-periodic mode: fires once when main counter = this comparator */ 45 /* periodic mode: fires when timer reaches this value, is increased by the original value */ 46 47 /* FSB Interrupt Route values */ 48 volatile uint32 fsb_value; 49 volatile uint32 fsb_addr; /* Where fsb_value should be written */ 50 51 volatile uint64 reserved; 52 }; 53 54 55 struct hpet_regs { 56 /* Capability bits */ 57 volatile uint32 period; 58 volatile uint32 capability; /* Capabilities */ 59 60 volatile uint64 reserved1; 61 62 /* Config Bits */ 63 volatile uint64 config; 64 65 volatile uint64 reserved2; 66 67 /* Interrupt Status bits */ 68 volatile uint64 timer_interrupts; /* Interrupt Config bits for timers 0-31 */ 69 /* Level Tigger: 0 = off, 1 = set by hardware, timer is active */ 70 /* Edge Trigger: ignored */ 71 /* Writing 0 will not clear these. Must write 1 again. */ 72 73 volatile uint8 reserved3[200]; 74 75 volatile uint64 counter; 76 77 volatile uint64 reserved4; 78 79 volatile struct hpet_timer timer0; 80 volatile struct hpet_timer timer1; 81 volatile struct hpet_timer timer2; 82 }; 83 84 85 typedef struct acpi_hpet { 86 acpi_descriptor_header header; /* "HPET" signature and acpi header */ 87 uint16 vendor_id; 88 uint8 legacy_capable : 1; 89 uint8 reserved1 : 1; 90 uint8 countersize : 1; 91 uint8 comparators : 5; 92 uint8 hw_revision; 93 struct hpet_addr { 94 uint8 address_space; 95 uint8 register_width; 96 uint8 register_offset; 97 uint8 reserved; 98 uint64 address; 99 } hpet_address; 100 uint8 number; 101 uint16 min_tick; 102 } _PACKED acpi_hpet; 103 104 #endif 105