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