Print this page
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/i86pc/sys/hpet_acpi.h
+++ new/usr/src/uts/i86pc/sys/hpet_acpi.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 #ifndef _HPET_ACPI_H
26 26 #define _HPET_ACPI_H
27 27
28 28 #if defined(_KERNEL)
29 -#include <sys/acpi/acpi.h>
30 -#include <sys/acpi/actbl1.h>
29 +#include <acpica/include/acpi.h>
30 +#include <acpica/include/actbl1.h>
31 31 #include <sys/acpica.h>
32 32 #endif /* defined(_KERNEL) */
33 33
34 34 #ifdef __cplusplus
35 35 extern "C" {
36 36 #endif
37 37
38 38 /*
39 39 * Solaris uses an HPET Timer to generate interrupts for CPUs in Deep C-state
40 40 * with stalled LAPIC Timers. All CPUs use one HPET timer. The timer's
41 41 * interrupt targets one CPU (via the I/O APIC). The one CPU that receives
42 42 * the HPET's interrupt wakes up other CPUs as needed during the HPET Interrupt
43 43 * Service Routing. The HPET ISR uses poke_cpus to wake up other CPUs with an
44 44 * Inter Processor Interrupt.
45 45 *
46 46 * Please see the Intel Programmer's guides. Interrupts are disabled before
47 47 * a CPU Halts into Deep C-state. (This allows CPU-hardware-specific cleanup
48 48 * before servicing interrupts.) When a Deep C-state CPU wakes up (due to
49 49 * an externally generated interrupt), it resume execution where it halted.
50 50 * The CPU returning from Deep C-state must enable interrupts before it will
51 51 * handle the pending interrupt that woke it from Deep C-state.
52 52 *
53 53 *
54 54 * HPET bits as defined in the Intel IA-PC HPET Specification Rev 1.0a.
55 55 *
56 56 * The physical address space layout of the memory mapped HPET looks like this:
57 57 *
58 58 * struct hpet {
59 59 * uint64_t gen_cap;
60 60 * uint64_t res1;
61 61 * uint64_t gen_config;
62 62 * uint64_t res2;
63 63 * uint64_t gen_inter_stat;
64 64 * uint64_t res3;
65 65 * uint64_t main_counter_value;
66 66 * uint64_t res4;
67 67 * stuct hpet_timer {
68 68 * uint64_t config_and_capability;
69 69 * uint64_t comparator_value;
70 70 * uint64_t FSB_interrupt_route;
71 71 * uint64_t reserved;
72 72 * } timers[32];
73 73 * }
74 74 *
75 75 * There are 32 possible timers in an hpet. Only the first 3 timers are
76 76 * required. The other 29 timers are optional.
77 77 *
78 78 * HPETs can have 64-bit or 32-bit timers. Timers/compare registers can
79 79 * be 64-bit or 32-bit and can be a mixture of both.
80 80 * The first two timers are not used. The HPET spec intends the first two
81 81 * timers to be used as "legacy replacement" for the PIT and RTC timers.
82 82 *
83 83 * Solaris uses the first available non-legacy replacement timer as a proxy
84 84 * timer for processor Local APIC Timers that stop in deep idle C-states.
85 85 */
86 86
87 87 /*
88 88 * We only use HPET table 1 on x86. Typical x86 systems only have 1 HPET.
89 89 * ACPI allows for multiple HPET tables to describe multiple HPETs.
90 90 */
91 91 #define HPET_TABLE_1 (1)
92 92
93 93 /*
94 94 * HPET Specification 1.0a defines the HPET to occupy 1024 bytes regardless of
95 95 * the number of counters (3 to 32) in this implementation.
96 96 */
97 97 #define HPET_SIZE (1024)
98 98
99 99 /*
100 100 * Offsets of hpet registers and macros to access them from HPET base address.
101 101 */
102 102 #define HPET_GEN_CAP_OFFSET (0)
103 103 #define HPET_GEN_CONFIG_OFFSET (0x10)
104 104 #define HPET_GEN_INTR_STAT_OFFSET (0x20)
105 105 #define HPET_MAIN_COUNTER_OFFSET (0xF0)
106 106 #define HPET_TIMER_N_CONF_OFFSET(n) (0x100 + (n * 0x20))
107 107 #define HPET_TIMER_N_COMP_OFFSET(n) (0x108 + (n * 0x20))
108 108
109 109 #define OFFSET_ADDR(a, o) (((uintptr_t)(a)) + (o))
110 110 #define HPET_GEN_CAP_ADDRESS(la) \
111 111 OFFSET_ADDR(la, HPET_GEN_CAP_OFFSET)
112 112 #define HPET_GEN_CONFIG_ADDRESS(la) \
113 113 OFFSET_ADDR(la, HPET_GEN_CONFIG_OFFSET)
114 114 #define HPET_GEN_INTR_STAT_ADDRESS(la) \
115 115 OFFSET_ADDR(la, HPET_GEN_INTR_STAT_OFFSET)
116 116 #define HPET_MAIN_COUNTER_ADDRESS(la) \
117 117 OFFSET_ADDR(la, HPET_MAIN_COUNTER_OFFSET)
118 118 #define HPET_TIMER_N_CONF_ADDRESS(la, n) \
119 119 OFFSET_ADDR(la, HPET_TIMER_N_CONF_OFFSET(n))
120 120 #define HPET_TIMER_N_COMP_ADDRESS(la, n) \
121 121 OFFSET_ADDR(la, HPET_TIMER_N_COMP_OFFSET(n))
122 122
123 123 /*
124 124 * HPET General Capabilities and ID Register
125 125 */
126 126 typedef struct hpet_gen_cap {
127 127 uint32_t counter_clk_period; /* period in femtoseconds */
128 128 uint32_t vendor_id :16; /* vendor */
129 129 uint32_t leg_route_cap :1; /* 1=LegacyReplacemnt support */
130 130 uint32_t res1 :1; /* reserved */
131 131 uint32_t count_size_cap :1; /* 0=32bit, 1=64bit wide */
132 132 uint32_t num_tim_cap :5; /* number of timers -1 */
133 133 uint32_t rev_id :8; /* revision number */
134 134 } hpet_gen_cap_t;
135 135
136 136 /*
137 137 * Macros to parse fields of the hpet General Capabilities and ID Register.
138 138 */
139 139 #define HPET_GCAP_CNTR_CLK_PERIOD(l) (l >> 32)
140 140 #define HPET_GCAP_VENDOR_ID(l) BITX(l, 31, 16)
141 141 #define HPET_GCAP_LEG_ROUTE_CAP(l) BITX(l, 15, 15)
142 142 #define HPET_GCAP_CNT_SIZE_CAP(l) BITX(l, 13, 13)
143 143 #define HPET_GCAP_NUM_TIM_CAP(l) BITX(l, 12, 8)
144 144 #define HPET_GCAP_REV_ID(l) BITX(l, 7, 0)
145 145
146 146 /*
147 147 * From HPET spec "The value in this field must be less than or equal to":
148 148 */
149 149 #define HPET_MAX_CLK_PERIOD (0x5F5E100)
150 150
151 151 /*
152 152 * Femto seconds in a second.
153 153 */
154 154 #if defined(__i386)
155 155 #define HPET_FEMTO_TO_NANO (1000000LL)
156 156 #define HRTIME_TO_HPET_TICKS(t) (((t) * HPET_FEMTO_TO_NANO) / hpet_info.period)
157 157 #else
158 158 #define HPET_FEMTO_TO_NANO (1000000L)
159 159 #define HRTIME_TO_HPET_TICKS(t) (((t) * HPET_FEMTO_TO_NANO) / hpet_info.period)
160 160 #endif /* (__i386) */
161 161
162 162 /*
163 163 * HPET General Configuration Register
164 164 */
165 165 typedef struct hpet_gen_config_bitfield {
166 166 uint32_t leg_rt_cnf :1; /* legacy replacement route */
167 167 uint32_t enable_cnf :1; /* overal enable */
168 168 } hpet_gen_conf_t;
169 169
170 170 /*
171 171 * General Configuration Register fields.
172 172 */
173 173 #define HPET_GCFR_LEG_RT_CNF (0x2) /* bit field value */
174 174 #define HPET_GCFR_ENABLE_CNF (0x1) /* bit field value */
175 175 #define HPET_GCFR_LEG_RT_CNF_BITX(l) BITX(l, 1, 1)
176 176 #define HPET_GCFR_ENABLE_CNF_BITX(l) BITX(l, 0, 0)
177 177
178 178 /*
179 179 * General Interrupt Status Register.
180 180 */
181 181 #define HPET_GIS_T2_INT_STS(l) BITX(l, 2, 2)
182 182 #define HPET_GIS_T1_INT_STS(l) BITX(l, 1, 1)
183 183 #define HPET_GIS_T0_INT_STS(l) BITX(l, 0, 0)
184 184 #define HPET_GIS_TN_INT_STS(l, n) BITX(l, n, n)
185 185
186 186 #define HPET_INTR_STATUS_MASK(timer) ((uint64_t)1 << (timer))
187 187
188 188 /*
189 189 * HPET Timer N Configuration and Capabilities Register
190 190 */
191 191 typedef struct hpet_TN_conf_cap {
192 192 uint32_t int_route_cap; /* available I/O APIC intrups */
193 193 uint32_t res1 :16; /* reserved */
194 194 uint32_t fsb_int_del_cap :1; /* FSB interrupt supported */
195 195 uint32_t fsb_int_en_cnf :1; /* Set FSB intr delivery */
196 196 uint32_t int_route_cnf :5; /* I/O APIC interrupt to use */
197 197 uint32_t mode32_cnf :1; /* Force 32-bit mode */
198 198 uint32_t res2 :1; /* reserved */
199 199 uint32_t val_set_cnf :1; /* Set periodic mode accumula */
200 200 uint32_t size_cap :1; /* 1=64bit, 0=32bit timer */
201 201 uint32_t per_int_cap :1; /* 1=periodic mode supported */
202 202 uint32_t type_cnf :1; /* Enable periodic mode */
203 203 uint32_t int_enb_cnf :1; /* Enable interrupt generat */
204 204 uint32_t int_type_cnf :1; /* 0=edge, 1=level triggered */
205 205 uint32_t res3 :1; /* reserved */
206 206 } hpet_TN_conf_cap_t;
207 207
208 208 /*
209 209 * There are 3 to 32 timers on each HPET.
210 210 */
211 211 #define HPET_TIMER_N_INT_ROUTE_CAP(l) (l >> 32)
212 212 #define HPET_TIMER_N_INT_TYPE_CNF(l) BITX(l, 1, 1)
213 213 #define HPET_TIMER_N_INT_ENB_CNF(l) BITX(l, 2, 2)
214 214 #define HPET_TIMER_N_TYPE_CNF(l) BITX(l, 3, 3)
215 215 #define HPET_TIMER_N_PER_INT_CAP(l) BITX(l, 4, 4)
216 216 #define HPET_TIMER_N_SIZE_CAP(l) BITX(l, 5, 5)
217 217 #define HPET_TIMER_N_VAL_SET_CNF(l) BITX(l, 6, 6)
218 218 #define HPET_TIMER_N_MODE32_CNF(l) BITX(l, 8, 8)
219 219 #define HPET_TIMER_N_INT_ROUTE_CNF(l) BITX(l, 13, 9)
220 220 #define HPET_TIMER_N_FSB_EN_CNF(l) BITX(l, 14, 14)
221 221 #define HPET_TIMER_N_FSB_INT_DEL_CAP(l) BITX(l, 15, 15)
222 222
223 223 #define HPET_TIMER_N_INT_TYPE_CNF_BIT (1 << 1)
224 224 #define HPET_TIMER_N_INT_ENB_CNF_BIT (1 << 2)
225 225 #define HPET_TIMER_N_TYPE_CNF_BIT (1 << 3)
226 226 #define HPET_TIMER_N_FSB_EN_CNF_BIT (1 << 14)
227 227 #define HPET_TIMER_N_INT_ROUTE_SHIFT(i) (i << 9)
228 228
229 229 /*
230 230 * HPET Spec reserves timers 0 and 1 for legacy timer replacement (PIT and RTC).
231 231 * Available timers for other use such as LACPI proxy during Deep C-State
232 232 * start at timer 2.
233 233 */
234 234 #define HPET_FIRST_NON_LEGACY_TIMER (2)
235 235
236 236 /*
237 237 * HPET timer and interrupt used as LAPIC proxy during deep C-State.
238 238 */
239 239 typedef struct cstate_timer {
240 240 int timer;
241 241 int intr;
242 242 } cstate_timer_t;
243 243
244 244 /*
245 245 * Data structure of useful HPET device information.
246 246 */
247 247 typedef struct hpet_info {
248 248 hpet_gen_cap_t gen_cap;
249 249 hpet_gen_conf_t gen_config;
250 250 uint64_t gen_intrpt_stat;
251 251 uint64_t main_counter_value;
252 252 void *logical_address; /* HPET VA memory map */
253 253 hpet_TN_conf_cap_t *timer_n_config; /* N Timer config and cap */
254 254 uint32_t num_timers; /* number of timers */
255 255 uint32_t allocated_timers; /* bitmap of timers in use */
256 256 cstate_timer_t cstate_timer; /* HPET Timer used for LAPIC proxy */
257 257 uint64_t hpet_main_counter_reads[2];
258 258 hrtime_t tsc[3];
259 259 hrtime_t period; /* counter_clk_period in Femto Secs */
260 260 } hpet_info_t;
261 261
262 262 #if defined(_KERNEL)
263 263
264 264 /*
265 265 * Spin mutexes are used in several places because idle threads cannot block.
266 266 * These defines provide a mechanism to break out of spin loops to prevent
267 267 * system hangs if a CPU can never get the lock (due to an unknown
268 268 * hardware/software bug). 100 microsecond was chosen after extensive stress
269 269 * testing.
270 270 */
271 271 #define HPET_SPIN_CHECK (1000)
272 272 #define HPET_SPIN_TIMEOUT (100000)
273 273
274 274 /*
275 275 * There is one of these per CPU using the HPET as a proxy for its stalled
276 276 * local APIC while in c-state >= C2.
277 277 */
278 278 typedef hrtime_t hpet_proxy_t;
279 279
280 280 extern ACPI_TABLE_HPET *hpet_table;
281 281 extern hpet_info_t hpet_info;
282 282
283 283 #endif /* defined(_KERNEL) */
284 284
285 285 #ifdef __cplusplus
286 286 }
287 287 #endif
288 288
289 289 #endif /* _HPET_ACPI_H */
↓ open down ↓ |
249 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX