1 /******************************************************************************
2 * arch/x86/hpet.c
3 *
4 * HPET management.
5 */
6
7 #include <xen/errno.h>
8 #include <xen/time.h>
9 #include <xen/timer.h>
10 #include <xen/smp.h>
11 #include <xen/softirq.h>
12 #include <xen/irq.h>
13 #include <xen/numa.h>
14 #include <xen/param.h>
15 #include <xen/sched.h>
16 #include <asm/fixmap.h>
17 #include <asm/div64.h>
18 #include <asm/hpet.h>
19 #include <asm/msi.h>
20 #include <mach_apic.h>
21 #include <xen/cpuidle.h>
22
23 #define MAX_DELTA_NS MILLISECS(10*1000)
24 #define MIN_DELTA_NS MICROSECS(20)
25
26 #define HPET_EVT_USED_BIT 0
27 #define HPET_EVT_USED (1 << HPET_EVT_USED_BIT)
28 #define HPET_EVT_DISABLE_BIT 1
29 #define HPET_EVT_DISABLE (1 << HPET_EVT_DISABLE_BIT)
30 #define HPET_EVT_LEGACY_BIT 2
31 #define HPET_EVT_LEGACY (1 << HPET_EVT_LEGACY_BIT)
32
33 struct hpet_event_channel
34 {
35 unsigned long mult;
36 int shift;
37 s_time_t next_event;
38 cpumask_var_t cpumask;
39 spinlock_t lock;
40 void (*event_handler)(struct hpet_event_channel *ch);
41
42 unsigned int idx; /* physical channel idx */
43 unsigned int cpu; /* msi target */
44 struct msi_desc msi;/* msi state */
45 unsigned int flags; /* HPET_EVT_x */
46 } __cacheline_aligned;
47 static struct hpet_event_channel *__read_mostly hpet_events;
48
49 /* msi hpet channels used for broadcast */
50 static unsigned int __read_mostly num_hpets_used;
51
52 static DEFINE_PER_CPU(struct hpet_event_channel *, cpu_bc_channel);
53
54 unsigned long __initdata hpet_address;
55 int8_t __initdata opt_hpet_legacy_replacement = -1;
56 static bool __initdata opt_hpet = true;
57 u8 __initdata hpet_blockid;
58 u8 __initdata hpet_flags;
59
60 /*
61 * force_hpet_broadcast: by default legacy hpet broadcast will be stopped
62 * if RTC interrupts are enabled. Enable this option if want to always enable
63 * legacy hpet broadcast for deep C state
64 */
65 static bool __initdata force_hpet_broadcast;
66 boolean_param("hpetbroadcast", force_hpet_broadcast);
67
parse_hpet_param(const char * s)68 static int __init cf_check parse_hpet_param(const char *s)
69 {
70 const char *ss;
71 int val, rc = 0;
72
73 do {
74 ss = strchr(s, ',');
75 if ( !ss )
76 ss = strchr(s, '\0');
77
78 if ( (val = parse_bool(s, ss)) >= 0 )
79 opt_hpet = val;
80 else if ( (val = parse_boolean("broadcast", s, ss)) >= 0 )
81 force_hpet_broadcast = val;
82 else if ( (val = parse_boolean("legacy-replacement", s, ss)) >= 0 )
83 opt_hpet_legacy_replacement = val;
84 else
85 rc = -EINVAL;
86
87 s = ss + 1;
88 } while ( *ss );
89
90 return rc;
91 }
92 custom_param("hpet", parse_hpet_param);
93
94 /*
95 * Calculate a multiplication factor for scaled math, which is used to convert
96 * nanoseconds based values to clock ticks:
97 *
98 * clock_ticks = (nanoseconds * factor) >> shift.
99 *
100 * div_sc is the rearranged equation to calculate a factor from a given clock
101 * ticks / nanoseconds ratio:
102 *
103 * factor = (clock_ticks << shift) / nanoseconds
104 */
div_sc(unsigned long ticks,unsigned long nsec,int shift)105 static inline unsigned long div_sc(unsigned long ticks, unsigned long nsec,
106 int shift)
107 {
108 return ((uint64_t)ticks << shift) / nsec;
109 }
110
111 /*
112 * Convert nanoseconds based values to clock ticks:
113 *
114 * clock_ticks = (nanoseconds * factor) >> shift.
115 */
ns2ticks(unsigned long nsec,int shift,unsigned long factor)116 static inline unsigned long ns2ticks(unsigned long nsec, int shift,
117 unsigned long factor)
118 {
119 uint64_t tmp = ((uint64_t)nsec * factor) >> shift;
120
121 return (unsigned long) tmp;
122 }
123
hpet_next_event(unsigned long delta,int timer)124 static int hpet_next_event(unsigned long delta, int timer)
125 {
126 uint32_t cnt, cmp;
127 unsigned long flags;
128
129 local_irq_save(flags);
130 cnt = hpet_read32(HPET_COUNTER);
131 cmp = cnt + delta;
132 hpet_write32(cmp, HPET_Tn_CMP(timer));
133 cmp = hpet_read32(HPET_COUNTER);
134 local_irq_restore(flags);
135
136 /* Are we within two ticks of the deadline passing? Then we may miss. */
137 return ((cmp + 2 - cnt) > delta) ? -ETIME : 0;
138 }
139
reprogram_hpet_evt_channel(struct hpet_event_channel * ch,s_time_t expire,s_time_t now,int force)140 static int reprogram_hpet_evt_channel(
141 struct hpet_event_channel *ch,
142 s_time_t expire, s_time_t now, int force)
143 {
144 int64_t delta;
145 int ret;
146
147 if ( (ch->flags & HPET_EVT_DISABLE) || (expire == 0) )
148 return 0;
149
150 if ( unlikely(expire < 0) )
151 {
152 printk(KERN_DEBUG "reprogram: expire <= 0\n");
153 return -ETIME;
154 }
155
156 delta = expire - now;
157 if ( (delta <= 0) && !force )
158 return -ETIME;
159
160 ch->next_event = expire;
161
162 if ( expire == STIME_MAX )
163 {
164 /* We assume it will take a long time for the timer to wrap. */
165 hpet_write32(0, HPET_Tn_CMP(ch->idx));
166 return 0;
167 }
168
169 delta = min_t(int64_t, delta, MAX_DELTA_NS);
170 delta = max_t(int64_t, delta, MIN_DELTA_NS);
171 delta = ns2ticks(delta, ch->shift, ch->mult);
172
173 ret = hpet_next_event(delta, ch->idx);
174 while ( ret && force )
175 {
176 delta += delta;
177 ret = hpet_next_event(delta, ch->idx);
178 }
179
180 return ret;
181 }
182
evt_do_broadcast(cpumask_t * mask)183 static void evt_do_broadcast(cpumask_t *mask)
184 {
185 unsigned int cpu = smp_processor_id();
186
187 if ( __cpumask_test_and_clear_cpu(cpu, mask) )
188 raise_softirq(TIMER_SOFTIRQ);
189
190 cpuidle_wakeup_mwait(mask);
191
192 if ( !cpumask_empty(mask) )
193 cpumask_raise_softirq(mask, TIMER_SOFTIRQ);
194 }
195
handle_hpet_broadcast(struct hpet_event_channel * ch)196 static void cf_check handle_hpet_broadcast(struct hpet_event_channel *ch)
197 {
198 cpumask_t mask;
199 s_time_t now, next_event;
200 unsigned int cpu;
201 unsigned long flags;
202
203 spin_lock_irqsave(&ch->lock, flags);
204
205 again:
206 ch->next_event = STIME_MAX;
207
208 spin_unlock_irqrestore(&ch->lock, flags);
209
210 next_event = STIME_MAX;
211 cpumask_clear(&mask);
212 now = NOW();
213
214 /* find all expired events */
215 for_each_cpu(cpu, ch->cpumask)
216 {
217 s_time_t deadline = ACCESS_ONCE(per_cpu(timer_deadline, cpu));
218
219 if ( deadline <= now )
220 __cpumask_set_cpu(cpu, &mask);
221 else if ( deadline < next_event )
222 next_event = deadline;
223 }
224
225 /* wakeup the cpus which have an expired event. */
226 evt_do_broadcast(&mask);
227
228 if ( next_event != STIME_MAX )
229 {
230 spin_lock_irqsave(&ch->lock, flags);
231
232 if ( next_event < ch->next_event &&
233 reprogram_hpet_evt_channel(ch, next_event, now, 0) )
234 goto again;
235
236 spin_unlock_irqrestore(&ch->lock, flags);
237 }
238 }
239
hpet_interrupt_handler(int irq,void * data)240 static void cf_check hpet_interrupt_handler(int irq, void *data)
241 {
242 struct hpet_event_channel *ch = data;
243
244 this_cpu(irq_count)--;
245
246 if ( !ch->event_handler )
247 {
248 printk(XENLOG_WARNING "Spurious HPET timer interrupt on HPET timer %d\n", ch->idx);
249 return;
250 }
251
252 ch->event_handler(ch);
253 }
254
hpet_msi_unmask(struct irq_desc * desc)255 static void cf_check hpet_msi_unmask(struct irq_desc *desc)
256 {
257 u32 cfg;
258 struct hpet_event_channel *ch = desc->action->dev_id;
259
260 cfg = hpet_read32(HPET_Tn_CFG(ch->idx));
261 cfg |= HPET_TN_ENABLE;
262 hpet_write32(cfg, HPET_Tn_CFG(ch->idx));
263 ch->msi.msi_attrib.host_masked = 0;
264 }
265
hpet_msi_mask(struct irq_desc * desc)266 static void cf_check hpet_msi_mask(struct irq_desc *desc)
267 {
268 u32 cfg;
269 struct hpet_event_channel *ch = desc->action->dev_id;
270
271 cfg = hpet_read32(HPET_Tn_CFG(ch->idx));
272 cfg &= ~HPET_TN_ENABLE;
273 hpet_write32(cfg, HPET_Tn_CFG(ch->idx));
274 ch->msi.msi_attrib.host_masked = 1;
275 }
276
hpet_msi_write(struct hpet_event_channel * ch,struct msi_msg * msg)277 static int hpet_msi_write(struct hpet_event_channel *ch, struct msi_msg *msg)
278 {
279 ch->msi.msg = *msg;
280
281 if ( iommu_intremap != iommu_intremap_off )
282 {
283 int rc = iommu_update_ire_from_msi(&ch->msi, msg);
284
285 if ( rc )
286 return rc;
287 }
288
289 hpet_write32(msg->data, HPET_Tn_ROUTE(ch->idx));
290 hpet_write32(msg->address_lo, HPET_Tn_ROUTE(ch->idx) + 4);
291
292 return 0;
293 }
294
hpet_msi_startup(struct irq_desc * desc)295 static unsigned int cf_check hpet_msi_startup(struct irq_desc *desc)
296 {
297 hpet_msi_unmask(desc);
298 return 0;
299 }
300
301 #define hpet_msi_shutdown hpet_msi_mask
302
hpet_msi_ack(struct irq_desc * desc)303 static void cf_check hpet_msi_ack(struct irq_desc *desc)
304 {
305 irq_complete_move(desc);
306 move_native_irq(desc);
307 ack_APIC_irq();
308 }
309
hpet_msi_set_affinity(struct irq_desc * desc,const cpumask_t * mask)310 static void cf_check hpet_msi_set_affinity(
311 struct irq_desc *desc, const cpumask_t *mask)
312 {
313 struct hpet_event_channel *ch = desc->action->dev_id;
314 struct msi_msg msg = ch->msi.msg;
315
316 msg.dest32 = set_desc_affinity(desc, mask);
317 if ( msg.dest32 == BAD_APICID )
318 return;
319
320 msg.data &= ~MSI_DATA_VECTOR_MASK;
321 msg.data |= MSI_DATA_VECTOR(desc->arch.vector);
322 msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
323 msg.address_lo |= MSI_ADDR_DEST_ID(msg.dest32);
324 if ( msg.data != ch->msi.msg.data || msg.dest32 != ch->msi.msg.dest32 )
325 hpet_msi_write(ch, &msg);
326 }
327
328 /*
329 * IRQ Chip for MSI HPET Devices,
330 */
331 static hw_irq_controller hpet_msi_type = {
332 .typename = "HPET-MSI",
333 .startup = hpet_msi_startup,
334 .shutdown = hpet_msi_shutdown,
335 .enable = hpet_msi_unmask,
336 .disable = hpet_msi_mask,
337 .ack = hpet_msi_ack,
338 .set_affinity = hpet_msi_set_affinity,
339 };
340
__hpet_setup_msi_irq(struct irq_desc * desc)341 static int __hpet_setup_msi_irq(struct irq_desc *desc)
342 {
343 struct msi_msg msg;
344
345 msi_compose_msg(desc->arch.vector, desc->arch.cpu_mask, &msg);
346 return hpet_msi_write(desc->action->dev_id, &msg);
347 }
348
hpet_setup_msi_irq(struct hpet_event_channel * ch)349 static int __init hpet_setup_msi_irq(struct hpet_event_channel *ch)
350 {
351 int ret;
352 u32 cfg = hpet_read32(HPET_Tn_CFG(ch->idx));
353 irq_desc_t *desc = irq_to_desc(ch->msi.irq);
354
355 if ( iommu_intremap != iommu_intremap_off )
356 {
357 ch->msi.hpet_id = hpet_blockid;
358 ret = iommu_setup_hpet_msi(&ch->msi);
359 if ( ret )
360 return ret;
361 }
362
363 /* set HPET Tn as oneshot */
364 cfg &= ~(HPET_TN_LEVEL | HPET_TN_PERIODIC);
365 cfg |= HPET_TN_FSB | HPET_TN_32BIT;
366 hpet_write32(cfg, HPET_Tn_CFG(ch->idx));
367
368 desc->handler = &hpet_msi_type;
369 ret = request_irq(ch->msi.irq, 0, hpet_interrupt_handler, "HPET", ch);
370 if ( ret >= 0 )
371 ret = __hpet_setup_msi_irq(desc);
372 if ( ret < 0 )
373 {
374 if ( iommu_intremap != iommu_intremap_off )
375 iommu_update_ire_from_msi(&ch->msi, NULL);
376 return ret;
377 }
378
379 desc->msi_desc = &ch->msi;
380
381 return 0;
382 }
383
hpet_assign_irq(struct hpet_event_channel * ch)384 static int __init hpet_assign_irq(struct hpet_event_channel *ch)
385 {
386 int irq;
387
388 if ( (irq = create_irq(NUMA_NO_NODE, false)) < 0 )
389 return irq;
390
391 ch->msi.irq = irq;
392 if ( hpet_setup_msi_irq(ch) )
393 {
394 destroy_irq(irq);
395 return -EINVAL;
396 }
397
398 return 0;
399 }
400
hpet_fsb_cap_lookup(void)401 static void __init hpet_fsb_cap_lookup(void)
402 {
403 u32 id;
404 unsigned int i, num_chs;
405
406 if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) )
407 return;
408
409 id = hpet_read32(HPET_ID);
410
411 num_chs = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
412 num_chs++; /* Value read out starts from 0 */
413
414 hpet_events = xzalloc_array(struct hpet_event_channel, num_chs);
415 if ( !hpet_events )
416 return;
417
418 for ( i = 0; i < num_chs && num_hpets_used < nr_cpu_ids; i++ )
419 {
420 struct hpet_event_channel *ch = &hpet_events[num_hpets_used];
421 u32 cfg = hpet_read32(HPET_Tn_CFG(i));
422
423 /* Only consider HPET timer with MSI support */
424 if ( !(cfg & HPET_TN_FSB_CAP) )
425 continue;
426
427 if ( !zalloc_cpumask_var(&ch->cpumask) )
428 {
429 if ( !num_hpets_used )
430 {
431 xfree(hpet_events);
432 hpet_events = NULL;
433 }
434 break;
435 }
436
437 ch->flags = 0;
438 ch->idx = i;
439
440 if ( hpet_assign_irq(ch) == 0 )
441 num_hpets_used++;
442 }
443
444 printk(XENLOG_INFO "HPET: %u timers usable for broadcast (%u total)\n",
445 num_hpets_used, num_chs);
446 }
447
hpet_get_channel(unsigned int cpu)448 static struct hpet_event_channel *hpet_get_channel(unsigned int cpu)
449 {
450 static unsigned int next_channel;
451 unsigned int i, next;
452 struct hpet_event_channel *ch;
453
454 if ( num_hpets_used == 0 )
455 return hpet_events;
456
457 if ( num_hpets_used >= nr_cpu_ids )
458 return &hpet_events[cpu];
459
460 next = arch_fetch_and_add(&next_channel, 1) % num_hpets_used;
461
462 /* try unused channel first */
463 for ( i = next; i < next + num_hpets_used; i++ )
464 {
465 ch = &hpet_events[i % num_hpets_used];
466 if ( !test_and_set_bit(HPET_EVT_USED_BIT, &ch->flags) )
467 {
468 ch->cpu = cpu;
469 return ch;
470 }
471 }
472
473 /* share a in-use channel */
474 ch = &hpet_events[next];
475 if ( !test_and_set_bit(HPET_EVT_USED_BIT, &ch->flags) )
476 ch->cpu = cpu;
477
478 return ch;
479 }
480
set_channel_irq_affinity(struct hpet_event_channel * ch)481 static void set_channel_irq_affinity(struct hpet_event_channel *ch)
482 {
483 struct irq_desc *desc = irq_to_desc(ch->msi.irq);
484
485 ASSERT(!local_irq_is_enabled());
486 spin_lock(&desc->lock);
487 hpet_msi_mask(desc);
488 hpet_msi_set_affinity(desc, cpumask_of(ch->cpu));
489 hpet_msi_unmask(desc);
490 spin_unlock(&desc->lock);
491
492 spin_unlock(&ch->lock);
493
494 /* We may have missed an interrupt due to the temporary masking. */
495 if ( ch->event_handler && ch->next_event < NOW() )
496 ch->event_handler(ch);
497 }
498
hpet_attach_channel(unsigned int cpu,struct hpet_event_channel * ch)499 static void hpet_attach_channel(unsigned int cpu,
500 struct hpet_event_channel *ch)
501 {
502 ASSERT(!local_irq_is_enabled());
503 spin_lock(&ch->lock);
504
505 per_cpu(cpu_bc_channel, cpu) = ch;
506
507 /* try to be the channel owner again while holding the lock */
508 if ( !test_and_set_bit(HPET_EVT_USED_BIT, &ch->flags) )
509 ch->cpu = cpu;
510
511 if ( ch->cpu != cpu )
512 spin_unlock(&ch->lock);
513 else
514 set_channel_irq_affinity(ch);
515 }
516
hpet_detach_channel(unsigned int cpu,struct hpet_event_channel * ch)517 static void hpet_detach_channel(unsigned int cpu,
518 struct hpet_event_channel *ch)
519 {
520 unsigned int next;
521
522 spin_lock_irq(&ch->lock);
523
524 ASSERT(ch == per_cpu(cpu_bc_channel, cpu));
525
526 per_cpu(cpu_bc_channel, cpu) = NULL;
527
528 if ( cpu != ch->cpu )
529 spin_unlock_irq(&ch->lock);
530 else if ( (next = cpumask_first(ch->cpumask)) >= nr_cpu_ids )
531 {
532 ch->cpu = -1;
533 clear_bit(HPET_EVT_USED_BIT, &ch->flags);
534 spin_unlock_irq(&ch->lock);
535 }
536 else
537 {
538 ch->cpu = next;
539 set_channel_irq_affinity(ch);
540 local_irq_enable();
541 }
542 }
543
544 #include <asm/mc146818rtc.h>
545
546 void (*__read_mostly pv_rtc_handler)(uint8_t index, uint8_t value);
547
handle_rtc_once(uint8_t index,uint8_t value)548 static void cf_check handle_rtc_once(uint8_t index, uint8_t value)
549 {
550 if ( index != RTC_REG_B )
551 return;
552
553 /* RTC Reg B, contain PIE/AIE/UIE */
554 if ( value & (RTC_PIE | RTC_AIE | RTC_UIE ) )
555 {
556 cpuidle_disable_deep_cstate();
557 ACCESS_ONCE(pv_rtc_handler) = NULL;
558 }
559 }
560
hpet_broadcast_init(void)561 void __init hpet_broadcast_init(void)
562 {
563 u64 hpet_rate = hpet_setup();
564 u32 hpet_id, cfg;
565 unsigned int i, n;
566
567 if ( hpet_rate == 0 || hpet_broadcast_is_available() )
568 return;
569
570 cfg = hpet_read32(HPET_CFG);
571
572 hpet_fsb_cap_lookup();
573 if ( num_hpets_used > 0 )
574 {
575 /* Stop HPET legacy interrupts */
576 cfg &= ~HPET_CFG_LEGACY;
577 n = num_hpets_used;
578 }
579 else
580 {
581 hpet_id = hpet_read32(HPET_ID);
582 if ( !(hpet_id & HPET_ID_LEGSUP) )
583 return;
584
585 if ( !hpet_events )
586 hpet_events = xzalloc(struct hpet_event_channel);
587 if ( !hpet_events || !zalloc_cpumask_var(&hpet_events->cpumask) )
588 return;
589 hpet_events->msi.irq = -1;
590
591 /* Start HPET legacy interrupts */
592 cfg |= HPET_CFG_LEGACY;
593 n = 1;
594
595 if ( !force_hpet_broadcast )
596 pv_rtc_handler = handle_rtc_once;
597 }
598
599 hpet_write32(cfg, HPET_CFG);
600
601 for ( i = 0; i < n; i++ )
602 {
603 if ( i == 0 && (cfg & HPET_CFG_LEGACY) )
604 {
605 /* set HPET T0 as oneshot */
606 cfg = hpet_read32(HPET_Tn_CFG(0));
607 cfg &= ~(HPET_TN_LEVEL | HPET_TN_PERIODIC);
608 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
609 hpet_write32(cfg, HPET_Tn_CFG(0));
610 }
611
612 /*
613 * The period is a femto seconds value. We need to calculate the scaled
614 * math multiplication factor for nanosecond to hpet tick conversion.
615 */
616 hpet_events[i].mult = div_sc((unsigned long)hpet_rate,
617 1000000000UL, 32);
618 hpet_events[i].shift = 32;
619 hpet_events[i].next_event = STIME_MAX;
620 spin_lock_init(&hpet_events[i].lock);
621 smp_wmb();
622 hpet_events[i].event_handler = handle_hpet_broadcast;
623
624 hpet_events[i].msi.msi_attrib.maskbit = 1;
625 hpet_events[i].msi.msi_attrib.pos = MSI_TYPE_HPET;
626 }
627
628 if ( !num_hpets_used )
629 hpet_events->flags = HPET_EVT_LEGACY;
630 }
631
hpet_broadcast_resume(void)632 void hpet_broadcast_resume(void)
633 {
634 u32 cfg;
635 unsigned int i, n;
636
637 if ( !hpet_events )
638 return;
639
640 hpet_resume(NULL);
641
642 cfg = hpet_read32(HPET_CFG);
643
644 if ( num_hpets_used > 0 )
645 {
646 /* Stop HPET legacy interrupts */
647 cfg &= ~HPET_CFG_LEGACY;
648 n = num_hpets_used;
649 }
650 else if ( hpet_events->flags & HPET_EVT_DISABLE )
651 return;
652 else
653 {
654 /* Start HPET legacy interrupts */
655 cfg |= HPET_CFG_LEGACY;
656 n = 1;
657 }
658
659 hpet_write32(cfg, HPET_CFG);
660
661 for ( i = 0; i < n; i++ )
662 {
663 if ( hpet_events[i].msi.irq >= 0 )
664 __hpet_setup_msi_irq(irq_to_desc(hpet_events[i].msi.irq));
665
666 /* set HPET Tn as oneshot */
667 cfg = hpet_read32(HPET_Tn_CFG(hpet_events[i].idx));
668 cfg &= ~(HPET_TN_LEVEL | HPET_TN_PERIODIC);
669 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
670 if ( !(hpet_events[i].flags & HPET_EVT_LEGACY) )
671 cfg |= HPET_TN_FSB;
672 hpet_write32(cfg, HPET_Tn_CFG(hpet_events[i].idx));
673
674 hpet_events[i].next_event = STIME_MAX;
675 }
676 }
677
hpet_disable_legacy_broadcast(void)678 void hpet_disable_legacy_broadcast(void)
679 {
680 u32 cfg;
681 unsigned long flags;
682
683 if ( !hpet_events || !(hpet_events->flags & HPET_EVT_LEGACY) )
684 return;
685
686 spin_lock_irqsave(&hpet_events->lock, flags);
687
688 hpet_events->flags |= HPET_EVT_DISABLE;
689
690 /* disable HPET T0 */
691 cfg = hpet_read32(HPET_Tn_CFG(0));
692 cfg &= ~HPET_TN_ENABLE;
693 hpet_write32(cfg, HPET_Tn_CFG(0));
694
695 /* Stop HPET legacy interrupts */
696 cfg = hpet_read32(HPET_CFG);
697 cfg &= ~HPET_CFG_LEGACY;
698 hpet_write32(cfg, HPET_CFG);
699
700 spin_unlock_irqrestore(&hpet_events->lock, flags);
701
702 smp_send_event_check_mask(&cpu_online_map);
703 }
704
hpet_broadcast_enter(void)705 void cf_check hpet_broadcast_enter(void)
706 {
707 unsigned int cpu = smp_processor_id();
708 struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
709 s_time_t deadline = per_cpu(timer_deadline, cpu);
710
711 if ( deadline == 0 )
712 return;
713
714 if ( !ch )
715 ch = hpet_get_channel(cpu);
716
717 ASSERT(!local_irq_is_enabled());
718
719 if ( !(ch->flags & HPET_EVT_LEGACY) )
720 hpet_attach_channel(cpu, ch);
721
722 /* Disable LAPIC timer interrupts. */
723 disable_APIC_timer();
724 cpumask_set_cpu(cpu, ch->cpumask);
725
726 spin_lock(&ch->lock);
727 /*
728 * Reprogram if current cpu expire time is nearer. deadline is never
729 * written by a remote cpu, so the value read earlier is still valid.
730 */
731 if ( deadline < ch->next_event )
732 reprogram_hpet_evt_channel(ch, deadline, NOW(), 1);
733 spin_unlock(&ch->lock);
734 }
735
hpet_broadcast_exit(void)736 void cf_check hpet_broadcast_exit(void)
737 {
738 unsigned int cpu = smp_processor_id();
739 struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
740 s_time_t deadline = per_cpu(timer_deadline, cpu);
741
742 if ( deadline == 0 )
743 return;
744
745 if ( !ch )
746 ch = hpet_get_channel(cpu);
747
748 /* Reprogram the deadline; trigger timer work now if it has passed. */
749 enable_APIC_timer();
750 if ( !reprogram_timer(deadline) )
751 raise_softirq(TIMER_SOFTIRQ);
752
753 cpumask_clear_cpu(cpu, ch->cpumask);
754
755 if ( !(ch->flags & HPET_EVT_LEGACY) )
756 hpet_detach_channel(cpu, ch);
757 }
758
hpet_broadcast_is_available(void)759 int hpet_broadcast_is_available(void)
760 {
761 return ((hpet_events && (hpet_events->flags & HPET_EVT_LEGACY))
762 || num_hpets_used > 0);
763 }
764
hpet_legacy_irq_tick(void)765 int hpet_legacy_irq_tick(void)
766 {
767 this_cpu(irq_count)--;
768
769 if ( !hpet_events ||
770 (hpet_events->flags & (HPET_EVT_DISABLE|HPET_EVT_LEGACY)) !=
771 HPET_EVT_LEGACY )
772 return 0;
773 hpet_events->event_handler(hpet_events);
774 return 1;
775 }
776
777 static u32 *hpet_boot_cfg;
778 static uint64_t __initdata hpet_rate;
779 static __initdata struct {
780 uint32_t cmp, cfg;
781 } pre_legacy_c0;
782
hpet_enable_legacy_replacement_mode(void)783 bool __init hpet_enable_legacy_replacement_mode(void)
784 {
785 unsigned int cfg, c0_cfg, ticks, count;
786
787 if ( !hpet_rate ||
788 !(hpet_read32(HPET_ID) & HPET_ID_LEGSUP) ||
789 ((cfg = hpet_read32(HPET_CFG)) & HPET_CFG_LEGACY) )
790 return false;
791
792 /* Stop the main counter. */
793 hpet_write32(cfg & ~HPET_CFG_ENABLE, HPET_CFG);
794
795 /* Stash channel 0's old CFG/CMP incase we need to undo. */
796 pre_legacy_c0.cfg = c0_cfg = hpet_read32(HPET_Tn_CFG(0));
797 pre_legacy_c0.cmp = hpet_read32(HPET_Tn_CMP(0));
798
799 /* Reconfigure channel 0 to be 32bit periodic. */
800 c0_cfg |= (HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
801 HPET_TN_32BIT);
802 hpet_write32(c0_cfg, HPET_Tn_CFG(0));
803
804 /*
805 * The exact period doesn't have to match a legacy PIT. All we need
806 * is an interrupt queued up via the IO-APIC to check routing.
807 *
808 * Use HZ as the frequency.
809 */
810 ticks = ((SECONDS(1) / HZ) * div_sc(hpet_rate, SECONDS(1), 32)) >> 32;
811
812 count = hpet_read32(HPET_COUNTER);
813
814 /*
815 * HPET_TN_SETVAL above is atrociously documented in the spec.
816 *
817 * Periodic HPET channels have a main comparator register, and
818 * separate "accumulator" register. Despite being named accumulator
819 * in the spec, this is not an accurate description of its behaviour
820 * or purpose.
821 *
822 * Each time an interrupt is generated, the "accumulator" register is
823 * re-added to the comparator set up the new period.
824 *
825 * Normally, writes to the CMP register update both registers.
826 * However, under these semantics, it is impossible to set up a
827 * periodic timer correctly without the main HPET counter being at 0.
828 *
829 * Instead, HPET_TN_SETVAL is a self-clearing control bit which we can
830 * use for periodic timers to mean that the second write to CMP
831 * updates the accumulator only, and not the absolute comparator
832 * value.
833 *
834 * This lets us set a period when the main counter isn't at 0.
835 */
836 hpet_write32(count + ticks, HPET_Tn_CMP(0));
837 hpet_write32(ticks, HPET_Tn_CMP(0));
838
839 /* Restart the main counter, and legacy mode. */
840 hpet_write32(cfg | HPET_CFG_ENABLE | HPET_CFG_LEGACY, HPET_CFG);
841
842 return true;
843 }
844
hpet_disable_legacy_replacement_mode(void)845 void __init hpet_disable_legacy_replacement_mode(void)
846 {
847 unsigned int cfg = hpet_read32(HPET_CFG);
848
849 ASSERT(hpet_rate);
850
851 cfg &= ~(HPET_CFG_LEGACY | HPET_CFG_ENABLE);
852
853 /* Stop the main counter and disable legacy mode. */
854 hpet_write32(cfg, HPET_CFG);
855
856 /* Restore pre-Legacy Replacement Mode settings. */
857 hpet_write32(pre_legacy_c0.cfg, HPET_Tn_CFG(0));
858 hpet_write32(pre_legacy_c0.cmp, HPET_Tn_CMP(0));
859
860 /* Restart the main counter. */
861 hpet_write32(cfg | HPET_CFG_ENABLE, HPET_CFG);
862 }
863
hpet_setup(void)864 u64 __init hpet_setup(void)
865 {
866 unsigned int hpet_id, hpet_period;
867 unsigned int last, rem;
868
869 if ( hpet_rate || !hpet_address || !opt_hpet )
870 return hpet_rate;
871
872 set_fixmap_nocache(FIX_HPET_BASE, hpet_address);
873
874 hpet_id = hpet_read32(HPET_ID);
875 if ( (hpet_id & HPET_ID_REV) == 0 )
876 {
877 printk("BAD HPET revision id.\n");
878 return 0;
879 }
880
881 /* Check for sane period (100ps <= period <= 100ns). */
882 hpet_period = hpet_read32(HPET_PERIOD);
883 if ( (hpet_period > 100000000) || (hpet_period < 100000) )
884 {
885 printk("BAD HPET period %u.\n", hpet_period);
886 return 0;
887 }
888
889 last = (hpet_id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
890 hpet_boot_cfg = xmalloc_array(u32, 2 + last);
891 hpet_resume(hpet_boot_cfg);
892
893 hpet_rate = 1000000000000000ULL; /* 10^15 */
894 rem = do_div(hpet_rate, hpet_period);
895 if ( (rem * 2) > hpet_period )
896 hpet_rate++;
897
898 if ( opt_hpet_legacy_replacement > 0 )
899 hpet_enable_legacy_replacement_mode();
900
901 return hpet_rate;
902 }
903
hpet_resume(uint32_t * boot_cfg)904 void hpet_resume(uint32_t *boot_cfg)
905 {
906 static u32 system_reset_latch;
907 u32 hpet_id, cfg;
908 unsigned int i, last;
909
910 if ( system_reset_latch == system_reset_counter )
911 return;
912 system_reset_latch = system_reset_counter;
913
914 cfg = hpet_read32(HPET_CFG);
915 if ( boot_cfg )
916 *boot_cfg = cfg;
917 cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
918 if ( cfg )
919 {
920 printk(XENLOG_WARNING
921 "HPET: reserved bits %#x set in global config register\n",
922 cfg);
923 cfg = 0;
924 }
925 hpet_write32(cfg, HPET_CFG);
926
927 hpet_id = hpet_read32(HPET_ID);
928 last = (hpet_id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
929 for ( i = 0; i <= last; ++i )
930 {
931 cfg = hpet_read32(HPET_Tn_CFG(i));
932 if ( boot_cfg )
933 boot_cfg[i + 1] = cfg;
934 cfg &= ~HPET_TN_ENABLE;
935 if ( cfg & HPET_TN_RESERVED )
936 {
937 printk(XENLOG_WARNING
938 "HPET: reserved bits %#x set in channel %u config register\n",
939 cfg & HPET_TN_RESERVED, i);
940 cfg &= ~HPET_TN_RESERVED;
941 }
942 hpet_write32(cfg, HPET_Tn_CFG(i));
943 }
944
945 cfg = hpet_read32(HPET_CFG);
946 cfg |= HPET_CFG_ENABLE;
947 hpet_write32(cfg, HPET_CFG);
948 }
949
hpet_disable(void)950 void hpet_disable(void)
951 {
952 unsigned int i;
953 u32 id;
954
955 if ( !hpet_boot_cfg )
956 {
957 if ( hpet_broadcast_is_available() )
958 hpet_disable_legacy_broadcast();
959 return;
960 }
961
962 hpet_write32(*hpet_boot_cfg & ~HPET_CFG_ENABLE, HPET_CFG);
963
964 id = hpet_read32(HPET_ID);
965 for ( i = 0; i <= ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT); ++i )
966 hpet_write32(hpet_boot_cfg[i + 1], HPET_Tn_CFG(i));
967
968 if ( *hpet_boot_cfg & HPET_CFG_ENABLE )
969 hpet_write32(*hpet_boot_cfg, HPET_CFG);
970 }
971