1 /*-
2 * Copyright (c) 2000, 2001 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_acpi.h"
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/eventhandler.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/sysctl.h>
38 #include <sys/timetc.h>
39
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 #include <sys/rman.h>
43
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46
47 #include <dev/acpica/acpivar.h>
48 #include <dev/pci/pcivar.h>
49
50 /*
51 * A timecounter based on the free-running ACPI timer.
52 *
53 * Based on the i386-only mp_clock.c by <[email protected]>.
54 */
55
56 /* Hooks for the ACPI CA debugging infrastructure */
57 #define _COMPONENT ACPI_TIMER
58 ACPI_MODULE_NAME("TIMER")
59
60 static device_t acpi_timer_dev;
61 static struct resource *acpi_timer_reg;
62 static bus_space_handle_t acpi_timer_bsh;
63 static bus_space_tag_t acpi_timer_bst;
64 static eventhandler_tag acpi_timer_eh;
65
66 static u_int acpi_timer_frequency = 14318182 / 4;
67
68 /* Knob to disable acpi_timer device */
69 bool acpi_timer_disabled = false;
70
71 static void acpi_timer_identify(driver_t *driver, device_t parent);
72 static int acpi_timer_probe(device_t dev);
73 static int acpi_timer_attach(device_t dev);
74 static void acpi_timer_resume_handler(struct timecounter *);
75 static void acpi_timer_suspend_handler(struct timecounter *);
76 static u_int acpi_timer_get_timecount(struct timecounter *tc);
77 static u_int acpi_timer_get_timecount_safe(struct timecounter *tc);
78 static int acpi_timer_sysctl_freq(SYSCTL_HANDLER_ARGS);
79 static void acpi_timer_boot_test(void);
80
81 static int acpi_timer_test(void);
82 #ifdef __i386__
83 static int acpi_timer_test_enabled = 1;
84 #else
85 static int acpi_timer_test_enabled = 0;
86 #endif
87 TUNABLE_INT("hw.acpi.timer_test_enabled", &acpi_timer_test_enabled);
88
89 static device_method_t acpi_timer_methods[] = {
90 DEVMETHOD(device_identify, acpi_timer_identify),
91 DEVMETHOD(device_probe, acpi_timer_probe),
92 DEVMETHOD(device_attach, acpi_timer_attach),
93
94 DEVMETHOD_END
95 };
96
97 static driver_t acpi_timer_driver = {
98 "acpi_timer",
99 acpi_timer_methods,
100 0,
101 };
102
103 static devclass_t acpi_timer_devclass;
104 DRIVER_MODULE(acpi_timer, acpi, acpi_timer_driver, acpi_timer_devclass, 0, 0);
105 MODULE_DEPEND(acpi_timer, acpi, 1, 1, 1);
106
107 static struct timecounter acpi_timer_timecounter = {
108 acpi_timer_get_timecount_safe, /* get_timecount function */
109 0, /* no poll_pps */
110 0, /* no default counter_mask */
111 0, /* no default frequency */
112 "ACPI", /* name */
113 -1 /* quality (chosen later) */
114 };
115
116 static __inline uint32_t
acpi_timer_read(void)117 acpi_timer_read(void)
118 {
119
120 return (bus_space_read_4(acpi_timer_bst, acpi_timer_bsh, 0));
121 }
122
123 /*
124 * Locate the ACPI timer using the FADT, set up and allocate the I/O resources
125 * we will be using.
126 */
127 static void
acpi_timer_identify(driver_t * driver,device_t parent)128 acpi_timer_identify(driver_t *driver, device_t parent)
129 {
130 device_t dev;
131 rman_res_t rlen, rstart;
132 int rid, rtype;
133
134 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
135
136 if (acpi_disabled("timer") || (acpi_quirks & ACPI_Q_TIMER) ||
137 acpi_timer_dev || acpi_timer_disabled ||
138 AcpiGbl_FADT.PmTimerLength == 0)
139 return_VOID;
140
141 if ((dev = BUS_ADD_CHILD(parent, 2, "acpi_timer", 0)) == NULL) {
142 device_printf(parent, "could not add acpi_timer0\n");
143 return_VOID;
144 }
145 acpi_timer_dev = dev;
146
147 switch (AcpiGbl_FADT.XPmTimerBlock.SpaceId) {
148 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
149 rtype = SYS_RES_MEMORY;
150 break;
151 case ACPI_ADR_SPACE_SYSTEM_IO:
152 rtype = SYS_RES_IOPORT;
153 break;
154 default:
155 return_VOID;
156 }
157 rid = 0;
158 rlen = AcpiGbl_FADT.PmTimerLength;
159 rstart = AcpiGbl_FADT.XPmTimerBlock.Address;
160 if (bus_set_resource(dev, rtype, rid, rstart, rlen))
161 device_printf(dev, "couldn't set resource (%s 0x%jx+0x%jx)\n",
162 (rtype == SYS_RES_IOPORT) ? "port" : "mem", rstart, rlen);
163 return_VOID;
164 }
165
166 static int
acpi_timer_probe(device_t dev)167 acpi_timer_probe(device_t dev)
168 {
169 char desc[40];
170 int i, j, rid, rtype;
171
172 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
173
174 if (dev != acpi_timer_dev)
175 return (ENXIO);
176
177 switch (AcpiGbl_FADT.XPmTimerBlock.SpaceId) {
178 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
179 rtype = SYS_RES_MEMORY;
180 break;
181 case ACPI_ADR_SPACE_SYSTEM_IO:
182 rtype = SYS_RES_IOPORT;
183 break;
184 default:
185 return (ENXIO);
186 }
187 rid = 0;
188 acpi_timer_reg = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE);
189 if (acpi_timer_reg == NULL) {
190 device_printf(dev, "couldn't allocate resource (%s 0x%lx)\n",
191 (rtype == SYS_RES_IOPORT) ? "port" : "mem",
192 (u_long)AcpiGbl_FADT.XPmTimerBlock.Address);
193 return (ENXIO);
194 }
195 acpi_timer_bsh = rman_get_bushandle(acpi_timer_reg);
196 acpi_timer_bst = rman_get_bustag(acpi_timer_reg);
197 if (AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER)
198 acpi_timer_timecounter.tc_counter_mask = 0xffffffff;
199 else
200 acpi_timer_timecounter.tc_counter_mask = 0x00ffffff;
201 acpi_timer_timecounter.tc_frequency = acpi_timer_frequency;
202 acpi_timer_timecounter.tc_flags = TC_FLAGS_SUSPEND_SAFE;
203 if (testenv("debug.acpi.timer_test"))
204 acpi_timer_boot_test();
205
206 /*
207 * If all tests of the counter succeed, use the ACPI-fast method. If
208 * at least one failed, default to using the safe routine, which reads
209 * the timer multiple times to get a consistent value before returning.
210 */
211 j = 0;
212 if (bootverbose)
213 printf("ACPI timer:");
214 for (i = 0; i < 10; i++)
215 j += acpi_timer_test();
216 if (bootverbose)
217 printf(" -> %d\n", j);
218 if (j == 10) {
219 acpi_timer_timecounter.tc_name = "ACPI-fast";
220 acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount;
221 acpi_timer_timecounter.tc_quality = 900;
222 } else {
223 acpi_timer_timecounter.tc_name = "ACPI-safe";
224 acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount_safe;
225 acpi_timer_timecounter.tc_quality = 850;
226 }
227 tc_init(&acpi_timer_timecounter);
228
229 sprintf(desc, "%d-bit timer at %u.%06uMHz",
230 (AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) != 0 ? 32 : 24,
231 acpi_timer_frequency / 1000000, acpi_timer_frequency % 1000000);
232 device_set_desc_copy(dev, desc);
233
234 /* Release the resource, we'll allocate it again during attach. */
235 bus_release_resource(dev, rtype, rid, acpi_timer_reg);
236 return (0);
237 }
238
239 static int
acpi_timer_attach(device_t dev)240 acpi_timer_attach(device_t dev)
241 {
242 int rid, rtype;
243
244 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
245
246 switch (AcpiGbl_FADT.XPmTimerBlock.SpaceId) {
247 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
248 rtype = SYS_RES_MEMORY;
249 break;
250 case ACPI_ADR_SPACE_SYSTEM_IO:
251 rtype = SYS_RES_IOPORT;
252 break;
253 default:
254 return (ENXIO);
255 }
256 rid = 0;
257 acpi_timer_reg = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE);
258 if (acpi_timer_reg == NULL)
259 return (ENXIO);
260 acpi_timer_bsh = rman_get_bushandle(acpi_timer_reg);
261 acpi_timer_bst = rman_get_bustag(acpi_timer_reg);
262
263 /* Register suspend event handler. */
264 if (EVENTHANDLER_REGISTER(power_suspend, acpi_timer_suspend_handler,
265 &acpi_timer_timecounter, EVENTHANDLER_PRI_LAST) == NULL)
266 device_printf(dev, "failed to register suspend event handler\n");
267
268 return (0);
269 }
270
271 static void
acpi_timer_resume_handler(struct timecounter * newtc)272 acpi_timer_resume_handler(struct timecounter *newtc)
273 {
274 struct timecounter *tc;
275
276 tc = timecounter;
277 if (tc != newtc) {
278 if (bootverbose)
279 device_printf(acpi_timer_dev,
280 "restoring timecounter, %s -> %s\n",
281 tc->tc_name, newtc->tc_name);
282 (void)newtc->tc_get_timecount(newtc);
283 timecounter = newtc;
284 }
285 }
286
287 static void
acpi_timer_suspend_handler(struct timecounter * newtc)288 acpi_timer_suspend_handler(struct timecounter *newtc)
289 {
290 struct timecounter *tc;
291
292 /* Deregister existing resume event handler. */
293 if (acpi_timer_eh != NULL) {
294 EVENTHANDLER_DEREGISTER(power_resume, acpi_timer_eh);
295 acpi_timer_eh = NULL;
296 }
297
298 if ((timecounter->tc_flags & TC_FLAGS_SUSPEND_SAFE) != 0) {
299 /*
300 * If we are using a suspend safe timecounter, don't
301 * save/restore it across suspend/resume.
302 */
303 return;
304 }
305
306 KASSERT(newtc == &acpi_timer_timecounter,
307 ("acpi_timer_suspend_handler: wrong timecounter"));
308
309 tc = timecounter;
310 if (tc != newtc) {
311 if (bootverbose)
312 device_printf(acpi_timer_dev,
313 "switching timecounter, %s -> %s\n",
314 tc->tc_name, newtc->tc_name);
315 (void)acpi_timer_read();
316 (void)acpi_timer_read();
317 timecounter = newtc;
318 acpi_timer_eh = EVENTHANDLER_REGISTER(power_resume,
319 acpi_timer_resume_handler, tc, EVENTHANDLER_PRI_LAST);
320 }
321 }
322
323 /*
324 * Fetch current time value from reliable hardware.
325 */
326 static u_int
acpi_timer_get_timecount(struct timecounter * tc)327 acpi_timer_get_timecount(struct timecounter *tc)
328 {
329 return (acpi_timer_read());
330 }
331
332 /*
333 * Fetch current time value from hardware that may not correctly
334 * latch the counter. We need to read until we have three monotonic
335 * samples and then use the middle one, otherwise we are not protected
336 * against the fact that the bits can be wrong in two directions. If
337 * we only cared about monosity, two reads would be enough.
338 */
339 static u_int
acpi_timer_get_timecount_safe(struct timecounter * tc)340 acpi_timer_get_timecount_safe(struct timecounter *tc)
341 {
342 u_int u1, u2, u3;
343
344 u2 = acpi_timer_read();
345 u3 = acpi_timer_read();
346 do {
347 u1 = u2;
348 u2 = u3;
349 u3 = acpi_timer_read();
350 } while (u1 > u2 || u2 > u3);
351
352 return (u2);
353 }
354
355 /*
356 * Timecounter freqency adjustment interface.
357 */
358 static int
acpi_timer_sysctl_freq(SYSCTL_HANDLER_ARGS)359 acpi_timer_sysctl_freq(SYSCTL_HANDLER_ARGS)
360 {
361 int error;
362 u_int freq;
363
364 if (acpi_timer_timecounter.tc_frequency == 0)
365 return (EOPNOTSUPP);
366 freq = acpi_timer_frequency;
367 error = sysctl_handle_int(oidp, &freq, 0, req);
368 if (error == 0 && req->newptr != NULL) {
369 acpi_timer_frequency = freq;
370 acpi_timer_timecounter.tc_frequency = acpi_timer_frequency;
371 }
372
373 return (error);
374 }
375
376 SYSCTL_PROC(_machdep, OID_AUTO, acpi_timer_freq,
377 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0,
378 acpi_timer_sysctl_freq, "I",
379 "ACPI timer frequency");
380
381 /*
382 * Some ACPI timers are known or believed to suffer from implementation
383 * problems which can lead to erroneous values being read. This function
384 * tests for consistent results from the timer and returns 1 if it believes
385 * the timer is consistent, otherwise it returns 0.
386 *
387 * It appears the cause is that the counter is not latched to the PCI bus
388 * clock when read:
389 *
390 * ] 20. ACPI Timer Errata
391 * ]
392 * ] Problem: The power management timer may return improper result when
393 * ] read. Although the timer value settles properly after incrementing,
394 * ] while incrementing there is a 3nS window every 69.8nS where the
395 * ] timer value is indeterminate (a 4.2% chance that the data will be
396 * ] incorrect when read). As a result, the ACPI free running count up
397 * ] timer specification is violated due to erroneous reads. Implication:
398 * ] System hangs due to the "inaccuracy" of the timer when used by
399 * ] software for time critical events and delays.
400 * ]
401 * ] Workaround: Read the register twice and compare.
402 * ] Status: This will not be fixed in the PIIX4 or PIIX4E, it is fixed
403 * ] in the PIIX4M.
404 */
405 #define N 2000
406 static int
acpi_timer_test()407 acpi_timer_test()
408 {
409 uint32_t last, this;
410 int delta, max, max2, min, n;
411 register_t s;
412
413 /* Skip the test based on the hw.acpi.timer_test_enabled tunable. */
414 if (!acpi_timer_test_enabled)
415 return (1);
416
417 TSENTER();
418
419 min = INT32_MAX;
420 max = max2 = 0;
421
422 /* Test the timer with interrupts disabled to get accurate results. */
423 s = intr_disable();
424 last = acpi_timer_read();
425 for (n = 0; n < N; n++) {
426 this = acpi_timer_read();
427 delta = acpi_TimerDelta(this, last);
428 if (delta > max) {
429 max2 = max;
430 max = delta;
431 } else if (delta > max2)
432 max2 = delta;
433 if (delta < min)
434 min = delta;
435 last = this;
436 }
437 intr_restore(s);
438
439 delta = max2 - min;
440 if ((max - min > 8 || delta > 3) && vm_guest == VM_GUEST_NO)
441 n = 0;
442 else if (min < 0 || max == 0 || max2 == 0)
443 n = 0;
444 else
445 n = 1;
446 if (bootverbose)
447 printf(" %d/%d", n, delta);
448
449 TSEXIT();
450
451 return (n);
452 }
453 #undef N
454
455 /*
456 * Test harness for verifying ACPI timer behaviour.
457 * Boot with debug.acpi.timer_test set to invoke this.
458 */
459 static void
acpi_timer_boot_test(void)460 acpi_timer_boot_test(void)
461 {
462 uint32_t u1, u2, u3;
463
464 u1 = acpi_timer_read();
465 u2 = acpi_timer_read();
466 u3 = acpi_timer_read();
467
468 device_printf(acpi_timer_dev, "timer test in progress, reboot to quit.\n");
469 for (;;) {
470 /*
471 * The failure case is where u3 > u1, but u2 does not fall between
472 * the two, ie. it contains garbage.
473 */
474 if (u3 > u1) {
475 if (u2 < u1 || u2 > u3)
476 device_printf(acpi_timer_dev,
477 "timer is not monotonic: 0x%08x,0x%08x,0x%08x\n",
478 u1, u2, u3);
479 }
480 u1 = u2;
481 u2 = u3;
482 u3 = acpi_timer_read();
483 }
484 }
485