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 <OS.h> 9 #include "arch_acpi.h" 10 11 /* All masks are 32 bits wide to represent relative bit locations */ 12 /* Doing it this way is Required since the HPET only supports 32/64-bit aligned reads. */ 13 14 /* Global Capability Register Masks */ 15 #define HPET_CAP_MASK_REVID 0x00000000000000FFULL 16 #define HPET_CAP_MASK_NUMTIMERS 0x0000000000001F00ULL 17 #define HPET_CAP_MASK_WIDTH 0x0000000000002000ULL 18 #define HPET_CAP_MASK_LEGACY 0x0000000000008000ULL 19 #define HPET_CAP_MASK_VENDOR_ID 0x00000000FFFF0000ULL 20 #define HPET_CAP_MASK_PERIOD 0xFFFFFFFF00000000ULL 21 22 /* Retrieve Global Capabilities */ 23 #define HPET_GET_REVID(regs) ((regs)->capabilities & HPET_CAP_MASK_REVID) 24 #define HPET_GET_NUM_TIMERS(regs) (((regs)->capabilities & HPET_CAP_MASK_NUMTIMERS) >> 8) 25 #define HPET_IS_64BIT(regs) (((regs)->capabilities & HPET_CAP_MASK_WIDTH) >> 13) 26 #define HPET_IS_LEGACY_CAPABLE(regs) (((regs)->capabilities & HPET_CAP_MASK_LEGACY) >> 15) 27 #define HPET_GET_VENDOR_ID(regs) (((regs)->capabilities & HPET_CAP_MASK_VENDOR_ID) >> 16) 28 #define HPET_GET_PERIOD(regs) (((regs)->capabilities & HPET_CAP_MASK_PERIOD) >> 32) 29 30 /* Global Config Register Masks */ 31 #define HPET_CONF_MASK_ENABLED 0x00000001 32 #define HPET_CONF_MASK_LEGACY 0x00000002 33 34 /* Retrieve Global Configuration */ 35 #define HPET_IS_ENABLED(regs) ((regs)->config & HPET_CONF_MASK_ENABLED) 36 #define HPET_IS_LEGACY(regs) (((regs)->config & HPET_CONF_MASK_LEGACY) >> 1) 37 38 /* Timer Configuration and Capabilities*/ 39 #define HPET_CAP_TIMER_MASK 0xFFFFFFFF00000000ULL 40 #define HPET_CAP_TIMER_PER_INT 0x00000010UL 41 #define HPET_CAP_TIMER_SIZE 0x00000020UL 42 #define HPET_CAP_TIMER_FSB_INT_DEL 0x00008000UL 43 #define HPET_GET_CAP_TIMER_ROUTE(timer) (((timer)->config & HPET_CAP_TIMER_MASK) >> 32) 44 45 #define HPET_CONF_TIMER_INT_ROUTE_MASK 0x3e00UL 46 #define HPET_CONF_TIMER_INT_ROUTE_SHIFT 9 47 #define HPET_CONF_TIMER_INT_TYPE 0x00000002UL 48 #define HPET_CONF_TIMER_INT_ENABLE 0x00000004UL 49 #define HPET_CONF_TIMER_TYPE 0x00000008UL 50 #define HPET_CONF_TIMER_VAL_SET 0x00000040UL 51 #define HPET_CONF_TIMER_32MODE 0x00000100UL 52 #define HPET_CONF_TIMER_FSB_ENABLE 0x00004000UL 53 #define HPET_GET_CONF_TIMER_INT_ROUTE(timer) (((timer)->config & HPET_CONF_TIMER_INT_ROUTE_MASK) >> HPET_CONF_TIMER_INT_ROUTE_SHIFT) 54 #define HPET_GET_CONF_TIMER_INT_IS_LEVEL(timer) (((timer)->config & HPET_CONF_TIMER_INT_TYPE)) 55 56 #define ACPI_HPET_SIGNATURE "HPET" 57 58 struct hpet_timer { 59 /* Timer Configuration/Capability bits, Reversed because x86 is LSB */ 60 volatile uint64 config; 61 /* R/W: Each bit represents one allowed interrupt for this timer. */ 62 /* If interrupt 16 is allowed, bit 16 will be 1. */ 63 union { 64 volatile uint64 comparator64; /* R/W: Comparator value */ 65 volatile uint32 comparator32; 66 } u0; /* non-periodic mode: fires once when main counter = this comparator */ 67 /* periodic mode: fires when timer reaches this value, is increased by the original value */ 68 69 volatile uint64 fsb_route[2]; /* R/W: FSB Interrupt Route values */ 70 }; 71 72 73 struct hpet_regs { 74 volatile uint64 capabilities; /* Read Only */ 75 76 volatile uint64 reserved1; 77 78 volatile uint64 config; /* R/W: Config Bits */ 79 80 volatile uint64 reserved2; 81 82 /* Interrupt Status bits */ 83 volatile uint64 interrupt_status; /* Interrupt Config bits for timers 0-31 */ 84 /* Level Tigger: 0 = off, 1 = set by hardware, timer is active */ 85 /* Edge Trigger: ignored */ 86 /* Writing 0 will not clear these. Must write 1 again. */ 87 uint64 reserved3[25]; 88 89 union { 90 volatile uint64 counter64; /* R/W */ 91 volatile uint32 counter32; 92 } u0; 93 94 uint64 reserved4; 95 96 struct hpet_timer timer[1]; 97 }; 98 99 100 typedef struct acpi_hpet { 101 acpi_descriptor_header header; /* "HPET" signature and acpi header */ 102 uint16 vendor_id; 103 uint8 legacy_capable : 1; 104 uint8 reserved1 : 1; 105 uint8 countersize : 1; 106 uint8 comparators : 5; 107 uint8 hw_revision; 108 struct hpet_addr { 109 uint8 address_space; 110 uint8 register_width; 111 uint8 register_offset; 112 uint8 reserved; 113 uint64 address; 114 } hpet_address; 115 uint8 number; 116 uint16 min_tick; 117 } _PACKED acpi_hpet; 118 119 #endif 120