10e751525SEric Saxe /* 20e751525SEric Saxe * CDDL HEADER START 30e751525SEric Saxe * 40e751525SEric Saxe * The contents of this file are subject to the terms of the 50e751525SEric Saxe * Common Development and Distribution License (the "License"). 60e751525SEric Saxe * You may not use this file except in compliance with the License. 70e751525SEric Saxe * 80e751525SEric Saxe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90e751525SEric Saxe * or http://www.opensolaris.org/os/licensing. 100e751525SEric Saxe * See the License for the specific language governing permissions 110e751525SEric Saxe * and limitations under the License. 120e751525SEric Saxe * 130e751525SEric Saxe * When distributing Covered Code, include this CDDL HEADER in each 140e751525SEric Saxe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150e751525SEric Saxe * If applicable, add the following below this CDDL HEADER, with the 160e751525SEric Saxe * fields enclosed by brackets "[]" replaced with your own identifying 170e751525SEric Saxe * information: Portions Copyright [yyyy] [name of copyright owner] 180e751525SEric Saxe * 190e751525SEric Saxe * CDDL HEADER END 200e751525SEric Saxe */ 210e751525SEric Saxe /* 22*5cd376e8SJimmy Vetayases * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 230e751525SEric Saxe */ 240e751525SEric Saxe 250e751525SEric Saxe #ifndef _HPET_ACPI_H 260e751525SEric Saxe #define _HPET_ACPI_H 270e751525SEric Saxe 280e751525SEric Saxe #if defined(_KERNEL) 290e751525SEric Saxe #include <sys/acpi/acpi.h> 300e751525SEric Saxe #include <sys/acpi/actbl1.h> 310e751525SEric Saxe #include <sys/acpica.h> 320e751525SEric Saxe #endif /* defined(_KERNEL) */ 330e751525SEric Saxe 340e751525SEric Saxe #ifdef __cplusplus 350e751525SEric Saxe extern "C" { 360e751525SEric Saxe #endif 370e751525SEric Saxe 380e751525SEric Saxe /* 390e751525SEric Saxe * Solaris uses an HPET Timer to generate interrupts for CPUs in Deep C-state 400e751525SEric Saxe * with stalled LAPIC Timers. All CPUs use one HPET timer. The timer's 410e751525SEric Saxe * interrupt targets one CPU (via the I/O APIC). The one CPU that receives 420e751525SEric Saxe * the HPET's interrupt wakes up other CPUs as needed during the HPET Interrupt 430e751525SEric Saxe * Service Routing. The HPET ISR uses poke_cpus to wake up other CPUs with an 440e751525SEric Saxe * Inter Processor Interrupt. 450e751525SEric Saxe * 460e751525SEric Saxe * Please see the Intel Programmer's guides. Interrupts are disabled before 470e751525SEric Saxe * a CPU Halts into Deep C-state. (This allows CPU-hardware-specific cleanup 480e751525SEric Saxe * before servicing interrupts.) When a Deep C-state CPU wakes up (due to 490e751525SEric Saxe * an externally generated interrupt), it resume execution where it halted. 500e751525SEric Saxe * The CPU returning from Deep C-state must enable interrupts before it will 510e751525SEric Saxe * handle the pending interrupt that woke it from Deep C-state. 520e751525SEric Saxe * 530e751525SEric Saxe * 540e751525SEric Saxe * HPET bits as defined in the Intel IA-PC HPET Specification Rev 1.0a. 550e751525SEric Saxe * 560e751525SEric Saxe * The physical address space layout of the memory mapped HPET looks like this: 570e751525SEric Saxe * 580e751525SEric Saxe * struct hpet { 590e751525SEric Saxe * uint64_t gen_cap; 600e751525SEric Saxe * uint64_t res1; 610e751525SEric Saxe * uint64_t gen_config; 620e751525SEric Saxe * uint64_t res2; 630e751525SEric Saxe * uint64_t gen_inter_stat; 640e751525SEric Saxe * uint64_t res3; 650e751525SEric Saxe * uint64_t main_counter_value; 660e751525SEric Saxe * uint64_t res4; 670e751525SEric Saxe * stuct hpet_timer { 680e751525SEric Saxe * uint64_t config_and_capability; 690e751525SEric Saxe * uint64_t comparator_value; 700e751525SEric Saxe * uint64_t FSB_interrupt_route; 710e751525SEric Saxe * uint64_t reserved; 720e751525SEric Saxe * } timers[32]; 730e751525SEric Saxe * } 740e751525SEric Saxe * 750e751525SEric Saxe * There are 32 possible timers in an hpet. Only the first 3 timers are 760e751525SEric Saxe * required. The other 29 timers are optional. 770e751525SEric Saxe * 780e751525SEric Saxe * HPETs can have 64-bit or 32-bit timers. Timers/compare registers can 790e751525SEric Saxe * be 64-bit or 32-bit and can be a mixture of both. 800e751525SEric Saxe * The first two timers are not used. The HPET spec intends the first two 810e751525SEric Saxe * timers to be used as "legacy replacement" for the PIT and RTC timers. 820e751525SEric Saxe * 830e751525SEric Saxe * Solaris uses the first available non-legacy replacement timer as a proxy 840e751525SEric Saxe * timer for processor Local APIC Timers that stop in deep idle C-states. 850e751525SEric Saxe */ 860e751525SEric Saxe 870e751525SEric Saxe /* 880e751525SEric Saxe * We only use HPET table 1 on x86. Typical x86 systems only have 1 HPET. 890e751525SEric Saxe * ACPI allows for multiple HPET tables to describe multiple HPETs. 900e751525SEric Saxe */ 910e751525SEric Saxe #define HPET_TABLE_1 (1) 920e751525SEric Saxe 930e751525SEric Saxe /* 940e751525SEric Saxe * HPET Specification 1.0a defines the HPET to occupy 1024 bytes regardless of 950e751525SEric Saxe * the number of counters (3 to 32) in this implementation. 960e751525SEric Saxe */ 970e751525SEric Saxe #define HPET_SIZE (1024) 980e751525SEric Saxe 990e751525SEric Saxe /* 1000e751525SEric Saxe * Offsets of hpet registers and macros to access them from HPET base address. 1010e751525SEric Saxe */ 1020e751525SEric Saxe #define HPET_GEN_CAP_OFFSET (0) 1030e751525SEric Saxe #define HPET_GEN_CONFIG_OFFSET (0x10) 1040e751525SEric Saxe #define HPET_GEN_INTR_STAT_OFFSET (0x20) 1050e751525SEric Saxe #define HPET_MAIN_COUNTER_OFFSET (0xF0) 1060e751525SEric Saxe #define HPET_TIMER_N_CONF_OFFSET(n) (0x100 + (n * 0x20)) 1070e751525SEric Saxe #define HPET_TIMER_N_COMP_OFFSET(n) (0x108 + (n * 0x20)) 1080e751525SEric Saxe 1090e751525SEric Saxe #define OFFSET_ADDR(a, o) (((uintptr_t)(a)) + (o)) 1100e751525SEric Saxe #define HPET_GEN_CAP_ADDRESS(la) \ 1110e751525SEric Saxe OFFSET_ADDR(la, HPET_GEN_CAP_OFFSET) 1120e751525SEric Saxe #define HPET_GEN_CONFIG_ADDRESS(la) \ 1130e751525SEric Saxe OFFSET_ADDR(la, HPET_GEN_CONFIG_OFFSET) 1140e751525SEric Saxe #define HPET_GEN_INTR_STAT_ADDRESS(la) \ 1150e751525SEric Saxe OFFSET_ADDR(la, HPET_GEN_INTR_STAT_OFFSET) 1160e751525SEric Saxe #define HPET_MAIN_COUNTER_ADDRESS(la) \ 1170e751525SEric Saxe OFFSET_ADDR(la, HPET_MAIN_COUNTER_OFFSET) 1180e751525SEric Saxe #define HPET_TIMER_N_CONF_ADDRESS(la, n) \ 1190e751525SEric Saxe OFFSET_ADDR(la, HPET_TIMER_N_CONF_OFFSET(n)) 1200e751525SEric Saxe #define HPET_TIMER_N_COMP_ADDRESS(la, n) \ 1210e751525SEric Saxe OFFSET_ADDR(la, HPET_TIMER_N_COMP_OFFSET(n)) 1220e751525SEric Saxe 1230e751525SEric Saxe /* 1240e751525SEric Saxe * HPET General Capabilities and ID Register 1250e751525SEric Saxe */ 1260e751525SEric Saxe typedef struct hpet_gen_cap { 1270e751525SEric Saxe uint32_t counter_clk_period; /* period in femtoseconds */ 1280e751525SEric Saxe uint32_t vendor_id :16; /* vendor */ 1290e751525SEric Saxe uint32_t leg_route_cap :1; /* 1=LegacyReplacemnt support */ 1300e751525SEric Saxe uint32_t res1 :1; /* reserved */ 1310e751525SEric Saxe uint32_t count_size_cap :1; /* 0=32bit, 1=64bit wide */ 1320e751525SEric Saxe uint32_t num_tim_cap :5; /* number of timers -1 */ 1330e751525SEric Saxe uint32_t rev_id :8; /* revision number */ 1340e751525SEric Saxe } hpet_gen_cap_t; 1350e751525SEric Saxe 1360e751525SEric Saxe /* 1370e751525SEric Saxe * Macros to parse fields of the hpet General Capabilities and ID Register. 1380e751525SEric Saxe */ 1390e751525SEric Saxe #define HPET_GCAP_CNTR_CLK_PERIOD(l) (l >> 32) 1400e751525SEric Saxe #define HPET_GCAP_VENDOR_ID(l) BITX(l, 31, 16) 1410e751525SEric Saxe #define HPET_GCAP_LEG_ROUTE_CAP(l) BITX(l, 15, 15) 1420e751525SEric Saxe #define HPET_GCAP_CNT_SIZE_CAP(l) BITX(l, 13, 13) 1430e751525SEric Saxe #define HPET_GCAP_NUM_TIM_CAP(l) BITX(l, 12, 8) 1440e751525SEric Saxe #define HPET_GCAP_REV_ID(l) BITX(l, 7, 0) 1450e751525SEric Saxe 1460e751525SEric Saxe /* 1470e751525SEric Saxe * From HPET spec "The value in this field must be less than or equal to": 1480e751525SEric Saxe */ 1490e751525SEric Saxe #define HPET_MAX_CLK_PERIOD (0x5F5E100) 1500e751525SEric Saxe 1510e751525SEric Saxe /* 1520e751525SEric Saxe * Femto seconds in a second. 1530e751525SEric Saxe */ 1540e751525SEric Saxe #if defined(__i386) 1550e751525SEric Saxe #define HPET_FEMTO_TO_NANO (1000000LL) 1560e751525SEric Saxe #define HRTIME_TO_HPET_TICKS(t) (((t) * HPET_FEMTO_TO_NANO) / hpet_info.period) 1570e751525SEric Saxe #else 1580e751525SEric Saxe #define HPET_FEMTO_TO_NANO (1000000L) 1590e751525SEric Saxe #define HRTIME_TO_HPET_TICKS(t) (((t) * HPET_FEMTO_TO_NANO) / hpet_info.period) 1600e751525SEric Saxe #endif /* (__i386) */ 1610e751525SEric Saxe 1620e751525SEric Saxe /* 1630e751525SEric Saxe * HPET General Configuration Register 1640e751525SEric Saxe */ 1650e751525SEric Saxe typedef struct hpet_gen_config_bitfield { 1660e751525SEric Saxe uint32_t leg_rt_cnf :1; /* legacy replacement route */ 1670e751525SEric Saxe uint32_t enable_cnf :1; /* overal enable */ 1680e751525SEric Saxe } hpet_gen_conf_t; 1690e751525SEric Saxe 1700e751525SEric Saxe /* 1710e751525SEric Saxe * General Configuration Register fields. 1720e751525SEric Saxe */ 1730e751525SEric Saxe #define HPET_GCFR_LEG_RT_CNF (0x2) /* bit field value */ 1740e751525SEric Saxe #define HPET_GCFR_ENABLE_CNF (0x1) /* bit field value */ 1750e751525SEric Saxe #define HPET_GCFR_LEG_RT_CNF_BITX(l) BITX(l, 1, 1) 1760e751525SEric Saxe #define HPET_GCFR_ENABLE_CNF_BITX(l) BITX(l, 0, 0) 1770e751525SEric Saxe 1780e751525SEric Saxe /* 1790e751525SEric Saxe * General Interrupt Status Register. 1800e751525SEric Saxe */ 1810e751525SEric Saxe #define HPET_GIS_T2_INT_STS(l) BITX(l, 2, 2) 1820e751525SEric Saxe #define HPET_GIS_T1_INT_STS(l) BITX(l, 1, 1) 1830e751525SEric Saxe #define HPET_GIS_T0_INT_STS(l) BITX(l, 0, 0) 1840e751525SEric Saxe #define HPET_GIS_TN_INT_STS(l, n) BITX(l, n, n) 1850e751525SEric Saxe 1860e751525SEric Saxe #define HPET_INTR_STATUS_MASK(timer) ((uint64_t)1 << (timer)) 1870e751525SEric Saxe 1880e751525SEric Saxe /* 1890e751525SEric Saxe * HPET Timer N Configuration and Capabilities Register 1900e751525SEric Saxe */ 1910e751525SEric Saxe typedef struct hpet_TN_conf_cap { 1920e751525SEric Saxe uint32_t int_route_cap; /* available I/O APIC intrups */ 1930e751525SEric Saxe uint32_t res1 :16; /* reserved */ 1940e751525SEric Saxe uint32_t fsb_int_del_cap :1; /* FSB interrupt supported */ 1950e751525SEric Saxe uint32_t fsb_int_en_cnf :1; /* Set FSB intr delivery */ 1960e751525SEric Saxe uint32_t int_route_cnf :5; /* I/O APIC interrupt to use */ 1970e751525SEric Saxe uint32_t mode32_cnf :1; /* Force 32-bit mode */ 1980e751525SEric Saxe uint32_t res2 :1; /* reserved */ 1990e751525SEric Saxe uint32_t val_set_cnf :1; /* Set periodic mode accumula */ 2000e751525SEric Saxe uint32_t size_cap :1; /* 1=64bit, 0=32bit timer */ 2010e751525SEric Saxe uint32_t per_int_cap :1; /* 1=periodic mode supported */ 2020e751525SEric Saxe uint32_t type_cnf :1; /* Enable periodic mode */ 2030e751525SEric Saxe uint32_t int_enb_cnf :1; /* Enable interrupt generat */ 2040e751525SEric Saxe uint32_t int_type_cnf :1; /* 0=edge, 1=level triggered */ 2050e751525SEric Saxe uint32_t res3 :1; /* reserved */ 2060e751525SEric Saxe } hpet_TN_conf_cap_t; 2070e751525SEric Saxe 2080e751525SEric Saxe /* 2090e751525SEric Saxe * There are 3 to 32 timers on each HPET. 2100e751525SEric Saxe */ 2110e751525SEric Saxe #define HPET_TIMER_N_INT_ROUTE_CAP(l) (l >> 32) 2120e751525SEric Saxe #define HPET_TIMER_N_INT_TYPE_CNF(l) BITX(l, 1, 1) 2130e751525SEric Saxe #define HPET_TIMER_N_INT_ENB_CNF(l) BITX(l, 2, 2) 2140e751525SEric Saxe #define HPET_TIMER_N_TYPE_CNF(l) BITX(l, 3, 3) 2150e751525SEric Saxe #define HPET_TIMER_N_PER_INT_CAP(l) BITX(l, 4, 4) 2160e751525SEric Saxe #define HPET_TIMER_N_SIZE_CAP(l) BITX(l, 5, 5) 2170e751525SEric Saxe #define HPET_TIMER_N_VAL_SET_CNF(l) BITX(l, 6, 6) 2180e751525SEric Saxe #define HPET_TIMER_N_MODE32_CNF(l) BITX(l, 8, 8) 2190e751525SEric Saxe #define HPET_TIMER_N_INT_ROUTE_CNF(l) BITX(l, 13, 9) 2200e751525SEric Saxe #define HPET_TIMER_N_FSB_EN_CNF(l) BITX(l, 14, 14) 2210e751525SEric Saxe #define HPET_TIMER_N_FSB_INT_DEL_CAP(l) BITX(l, 15, 15) 2220e751525SEric Saxe 2230e751525SEric Saxe #define HPET_TIMER_N_INT_TYPE_CNF_BIT (1 << 1) 2240e751525SEric Saxe #define HPET_TIMER_N_INT_ENB_CNF_BIT (1 << 2) 2250e751525SEric Saxe #define HPET_TIMER_N_TYPE_CNF_BIT (1 << 3) 2260e751525SEric Saxe #define HPET_TIMER_N_FSB_EN_CNF_BIT (1 << 14) 2270e751525SEric Saxe #define HPET_TIMER_N_INT_ROUTE_SHIFT(i) (i << 9) 2280e751525SEric Saxe 2290e751525SEric Saxe /* 2300e751525SEric Saxe * HPET Spec reserves timers 0 and 1 for legacy timer replacement (PIT and RTC). 2310e751525SEric Saxe * Available timers for other use such as LACPI proxy during Deep C-State 2320e751525SEric Saxe * start at timer 2. 2330e751525SEric Saxe */ 2340e751525SEric Saxe #define HPET_FIRST_NON_LEGACY_TIMER (2) 2350e751525SEric Saxe 2360e751525SEric Saxe /* 2370e751525SEric Saxe * HPET timer and interrupt used as LAPIC proxy during deep C-State. 2380e751525SEric Saxe */ 2390e751525SEric Saxe typedef struct cstate_timer { 2400e751525SEric Saxe int timer; 2410e751525SEric Saxe int intr; 2420e751525SEric Saxe } cstate_timer_t; 2430e751525SEric Saxe 2440e751525SEric Saxe /* 2450e751525SEric Saxe * Data structure of useful HPET device information. 2460e751525SEric Saxe */ 2470e751525SEric Saxe typedef struct hpet_info { 2480e751525SEric Saxe hpet_gen_cap_t gen_cap; 2490e751525SEric Saxe hpet_gen_conf_t gen_config; 2500e751525SEric Saxe uint64_t gen_intrpt_stat; 2510e751525SEric Saxe uint64_t main_counter_value; 2520e751525SEric Saxe void *logical_address; /* HPET VA memory map */ 2530e751525SEric Saxe hpet_TN_conf_cap_t *timer_n_config; /* N Timer config and cap */ 2540e751525SEric Saxe uint32_t num_timers; /* number of timers */ 2550e751525SEric Saxe uint32_t allocated_timers; /* bitmap of timers in use */ 2560e751525SEric Saxe cstate_timer_t cstate_timer; /* HPET Timer used for LAPIC proxy */ 2570e751525SEric Saxe uint64_t hpet_main_counter_reads[2]; 2580e751525SEric Saxe hrtime_t tsc[3]; 2590e751525SEric Saxe hrtime_t period; /* counter_clk_period in Femto Secs */ 2600e751525SEric Saxe } hpet_info_t; 2610e751525SEric Saxe 2620e751525SEric Saxe #if defined(_KERNEL) 2630e751525SEric Saxe 2640e751525SEric Saxe /* 2650e751525SEric Saxe * Spin mutexes are used in several places because idle threads cannot block. 2660e751525SEric Saxe * These defines provide a mechanism to break out of spin loops to prevent 2670e751525SEric Saxe * system hangs if a CPU can never get the lock (due to an unknown 2680e751525SEric Saxe * hardware/software bug). 100 microsecond was chosen after extensive stress 2690e751525SEric Saxe * testing. 2700e751525SEric Saxe */ 2710e751525SEric Saxe #define HPET_SPIN_CHECK (1000) 2720e751525SEric Saxe #define HPET_SPIN_TIMEOUT (100000) 2730e751525SEric Saxe 2740e751525SEric Saxe /* 2750e751525SEric Saxe * There is one of these per CPU using the HPET as a proxy for its stalled 2760e751525SEric Saxe * local APIC while in c-state >= C2. 2770e751525SEric Saxe */ 2780e751525SEric Saxe typedef hrtime_t hpet_proxy_t; 2790e751525SEric Saxe 2800e751525SEric Saxe extern ACPI_TABLE_HPET *hpet_table; 2810e751525SEric Saxe extern hpet_info_t hpet_info; 2820e751525SEric Saxe 2830e751525SEric Saxe #endif /* defined(_KERNEL) */ 2840e751525SEric Saxe 2850e751525SEric Saxe #ifdef __cplusplus 2860e751525SEric Saxe } 2870e751525SEric Saxe #endif 2880e751525SEric Saxe 2890e751525SEric Saxe #endif /* _HPET_ACPI_H */ 290