1 /*
2  * xen/arch/arm/time.c
3  *
4  * Time and timer support, using the ARM Generic Timer interfaces
5  *
6  * Tim Deegan <tim@xen.org>
7  * Copyright (c) 2011 Citrix Systems.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  */
19 
20 #include <xen/console.h>
21 #include <xen/device_tree.h>
22 #include <xen/init.h>
23 #include <xen/irq.h>
24 #include <xen/lib.h>
25 #include <xen/mm.h>
26 #include <xen/softirq.h>
27 #include <xen/sched.h>
28 #include <xen/time.h>
29 #include <xen/sched.h>
30 #include <xen/event.h>
31 #include <xen/acpi.h>
32 #include <xen/cpu.h>
33 #include <xen/notifier.h>
34 #include <asm/system.h>
35 #include <asm/time.h>
36 #include <asm/vgic.h>
37 #include <asm/cpufeature.h>
38 #include <asm/platform.h>
39 
40 uint64_t __read_mostly boot_count;
41 
42 /* For fine-grained timekeeping, we use the ARM "Generic Timer", a
43  * register-mapped time source in the SoC. */
44 unsigned long __read_mostly cpu_khz;  /* CPU clock frequency in kHz. */
45 
46 uint32_t __read_mostly timer_dt_clock_frequency;
47 
48 static unsigned int timer_irq[MAX_TIMER_PPI];
49 
timer_get_irq(enum timer_ppi ppi)50 unsigned int timer_get_irq(enum timer_ppi ppi)
51 {
52     ASSERT(ppi >= TIMER_PHYS_SECURE_PPI && ppi < MAX_TIMER_PPI);
53 
54     return timer_irq[ppi];
55 }
56 
ticks_to_ns(uint64_t ticks)57 /*static inline*/ s_time_t ticks_to_ns(uint64_t ticks)
58 {
59     return muldiv64(ticks, SECONDS(1), 1000 * cpu_khz);
60 }
61 
ns_to_ticks(s_time_t ns)62 /*static inline*/ uint64_t ns_to_ticks(s_time_t ns)
63 {
64     return muldiv64(ns, 1000 * cpu_khz, SECONDS(1));
65 }
66 
67 static __initdata struct dt_device_node *timer;
68 
69 #ifdef CONFIG_ACPI
acpi_get_timer_irq_type(u32 flags)70 static u32 __init acpi_get_timer_irq_type(u32 flags)
71 {
72     return (flags & ACPI_GTDT_INTERRUPT_MODE) ? IRQ_TYPE_EDGE_BOTH
73                                               : IRQ_TYPE_LEVEL_MASK;
74 }
75 
76 /* Initialize per-processor generic timer */
arch_timer_acpi_init(struct acpi_table_header * header)77 static int __init arch_timer_acpi_init(struct acpi_table_header *header)
78 {
79     u32 irq_type;
80     struct acpi_table_gtdt *gtdt;
81 
82     gtdt = container_of(header, struct acpi_table_gtdt, header);
83 
84     /* Initialize all the generic timer IRQ variable from GTDT table */
85     irq_type = acpi_get_timer_irq_type(gtdt->non_secure_el1_flags);
86     irq_set_type(gtdt->non_secure_el1_interrupt, irq_type);
87     timer_irq[TIMER_PHYS_NONSECURE_PPI] = gtdt->non_secure_el1_interrupt;
88 
89     irq_type = acpi_get_timer_irq_type(gtdt->secure_el1_flags);
90     irq_set_type(gtdt->secure_el1_interrupt, irq_type);
91     timer_irq[TIMER_PHYS_SECURE_PPI] = gtdt->secure_el1_interrupt;
92 
93     irq_type = acpi_get_timer_irq_type(gtdt->virtual_timer_flags);
94     irq_set_type(gtdt->virtual_timer_interrupt, irq_type);
95     timer_irq[TIMER_VIRT_PPI] = gtdt->virtual_timer_interrupt;
96 
97     irq_type = acpi_get_timer_irq_type(gtdt->non_secure_el2_flags);
98     irq_set_type(gtdt->non_secure_el2_interrupt, irq_type);
99     timer_irq[TIMER_HYP_PPI] = gtdt->non_secure_el2_interrupt;
100 
101     return 0;
102 }
103 
preinit_acpi_xen_time(void)104 static void __init preinit_acpi_xen_time(void)
105 {
106     acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
107 }
108 #else
preinit_acpi_xen_time(void)109 static void __init preinit_acpi_xen_time(void) { }
110 #endif
111 
112 /* Set up the timer on the boot CPU (early init function) */
preinit_dt_xen_time(void)113 static void __init preinit_dt_xen_time(void)
114 {
115     static const struct dt_device_match timer_ids[] __initconst =
116     {
117         DT_MATCH_TIMER,
118         { /* sentinel */ },
119     };
120     int res;
121     u32 rate;
122 
123     timer = dt_find_matching_node(NULL, timer_ids);
124     if ( !timer )
125         panic("Unable to find a compatible timer in the device tree\n");
126 
127     dt_device_set_used_by(timer, DOMID_XEN);
128 
129     res = dt_property_read_u32(timer, "clock-frequency", &rate);
130     if ( res )
131     {
132         cpu_khz = rate / 1000;
133         timer_dt_clock_frequency = rate;
134     }
135 }
136 
preinit_xen_time(void)137 void __init preinit_xen_time(void)
138 {
139     int res;
140 
141     /* Initialize all the generic timers presented in GTDT */
142     if ( acpi_disabled )
143         preinit_dt_xen_time();
144     else
145         preinit_acpi_xen_time();
146 
147     if ( !cpu_khz )
148         cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000;
149 
150     res = platform_init_time();
151     if ( res )
152         panic("Timer: Cannot initialize platform timer\n");
153 
154     boot_count = get_cycles();
155 }
156 
init_dt_xen_time(void)157 static void __init init_dt_xen_time(void)
158 {
159     int res;
160     unsigned int i;
161 
162     /* Retrieve all IRQs for the timer */
163     for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
164     {
165         res = platform_get_irq(timer, i);
166 
167         if ( res < 0 )
168             panic("Timer: Unable to retrieve IRQ %u from the device tree\n", i);
169         timer_irq[i] = res;
170     }
171 }
172 
173 /* Set up the timer on the boot CPU (late init function) */
init_xen_time(void)174 int __init init_xen_time(void)
175 {
176     if ( acpi_disabled )
177         init_dt_xen_time();
178 
179     /* Check that this CPU supports the Generic Timer interface */
180     if ( !cpu_has_gentimer )
181         panic("CPU does not support the Generic Timer v1 interface\n");
182 
183     printk("Generic Timer IRQ: phys=%u hyp=%u virt=%u Freq: %lu KHz\n",
184            timer_irq[TIMER_PHYS_NONSECURE_PPI],
185            timer_irq[TIMER_HYP_PPI],
186            timer_irq[TIMER_VIRT_PPI],
187            cpu_khz);
188 
189     return 0;
190 }
191 
192 /* Return number of nanoseconds since boot */
get_s_time(void)193 s_time_t get_s_time(void)
194 {
195     uint64_t ticks = get_cycles() - boot_count;
196     return ticks_to_ns(ticks);
197 }
198 
199 /* Set the timer to wake us up at a particular time.
200  * Timeout is a Xen system time (nanoseconds since boot); 0 disables the timer.
201  * Returns 1 on success; 0 if the timeout is too soon or is in the past. */
reprogram_timer(s_time_t timeout)202 int reprogram_timer(s_time_t timeout)
203 {
204     uint64_t deadline;
205 
206     if ( timeout == 0 )
207     {
208         WRITE_SYSREG32(0, CNTHP_CTL_EL2);
209         return 1;
210     }
211 
212     deadline = ns_to_ticks(timeout) + boot_count;
213     WRITE_SYSREG64(deadline, CNTHP_CVAL_EL2);
214     WRITE_SYSREG32(CNTx_CTL_ENABLE, CNTHP_CTL_EL2);
215     isb();
216 
217     /* No need to check for timers in the past; the Generic Timer fires
218      * on a signed 63-bit comparison. */
219     return 1;
220 }
221 
222 /* Handle the firing timer */
timer_interrupt(int irq,void * dev_id,struct cpu_user_regs * regs)223 static void timer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
224 {
225     if ( irq == (timer_irq[TIMER_HYP_PPI]) &&
226          READ_SYSREG32(CNTHP_CTL_EL2) & CNTx_CTL_PENDING )
227     {
228         perfc_incr(hyp_timer_irqs);
229         /* Signal the generic timer code to do its work */
230         raise_softirq(TIMER_SOFTIRQ);
231         /* Disable the timer to avoid more interrupts */
232         WRITE_SYSREG32(0, CNTHP_CTL_EL2);
233     }
234 
235     if ( irq == (timer_irq[TIMER_PHYS_NONSECURE_PPI]) &&
236          READ_SYSREG32(CNTP_CTL_EL0) & CNTx_CTL_PENDING )
237     {
238         perfc_incr(phys_timer_irqs);
239         /* Signal the generic timer code to do its work */
240         raise_softirq(TIMER_SOFTIRQ);
241         /* Disable the timer to avoid more interrupts */
242         WRITE_SYSREG32(0, CNTP_CTL_EL0);
243     }
244 }
245 
vtimer_interrupt(int irq,void * dev_id,struct cpu_user_regs * regs)246 static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
247 {
248     /*
249      * Edge-triggered interrupts can be used for the virtual timer. Even
250      * if the timer output signal is masked in the context switch, the
251      * GIC will keep track that of any interrupts raised while IRQS are
252      * disabled. As soon as IRQs are re-enabled, the virtual interrupt
253      * will be injected to Xen.
254      *
255      * If an IDLE vCPU was scheduled next then we should ignore the
256      * interrupt.
257      */
258     if ( unlikely(is_idle_vcpu(current)) )
259         return;
260 
261     perfc_incr(virt_timer_irqs);
262 
263     current->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0);
264     WRITE_SYSREG32(current->arch.virt_timer.ctl | CNTx_CTL_MASK, CNTV_CTL_EL0);
265     vgic_inject_irq(current->domain, current, current->arch.virt_timer.irq, true);
266 }
267 
268 /*
269  * Arch timer interrupt really ought to be level triggered, since the
270  * design of the timer/comparator mechanism is based around that
271  * concept.
272  *
273  * However some firmware (incorrectly) describes the interrupts as
274  * edge triggered and, worse, some hardware allows us to program the
275  * interrupt controller as edge triggered.
276  *
277  * Check each interrupt and warn if we find ourselves in this situation.
278  */
check_timer_irq_cfg(unsigned int irq,const char * which)279 static void check_timer_irq_cfg(unsigned int irq, const char *which)
280 {
281     struct irq_desc *desc = irq_to_desc(irq);
282 
283     /*
284      * The interrupt controller driver will update desc->arch.type with
285      * the actual type which ended up configured in the hardware.
286      */
287     if ( desc->arch.type & IRQ_TYPE_LEVEL_MASK )
288         return;
289 
290     printk(XENLOG_WARNING
291            "WARNING: %s-timer IRQ%u is not level triggered.\n", which, irq);
292 }
293 
294 /* Set up the timer interrupt on this CPU */
init_timer_interrupt(void)295 void init_timer_interrupt(void)
296 {
297     /* Sensible defaults */
298     WRITE_SYSREG64(0, CNTVOFF_EL2);     /* No VM-specific offset */
299     /* Do not let the VMs program the physical timer, only read the physical counter */
300     WRITE_SYSREG32(CNTHCTL_EL2_EL1PCTEN, CNTHCTL_EL2);
301     WRITE_SYSREG32(0, CNTP_CTL_EL0);    /* Physical timer disabled */
302     WRITE_SYSREG32(0, CNTHP_CTL_EL2);   /* Hypervisor's timer disabled */
303     isb();
304 
305     request_irq(timer_irq[TIMER_HYP_PPI], 0, timer_interrupt,
306                 "hyptimer", NULL);
307     request_irq(timer_irq[TIMER_VIRT_PPI], 0, vtimer_interrupt,
308                    "virtimer", NULL);
309     request_irq(timer_irq[TIMER_PHYS_NONSECURE_PPI], 0, timer_interrupt,
310                 "phytimer", NULL);
311 
312     check_timer_irq_cfg(timer_irq[TIMER_HYP_PPI], "hypervisor");
313     check_timer_irq_cfg(timer_irq[TIMER_VIRT_PPI], "virtual");
314     check_timer_irq_cfg(timer_irq[TIMER_PHYS_NONSECURE_PPI], "NS-physical");
315 }
316 
317 /*
318  * Revert actions done in init_timer_interrupt that are required to properly
319  * disable this CPU.
320  */
deinit_timer_interrupt(void)321 static void deinit_timer_interrupt(void)
322 {
323     WRITE_SYSREG32(0, CNTP_CTL_EL0);    /* Disable physical timer */
324     WRITE_SYSREG32(0, CNTHP_CTL_EL2);   /* Disable hypervisor's timer */
325     isb();
326 
327     release_irq(timer_irq[TIMER_HYP_PPI], NULL);
328     release_irq(timer_irq[TIMER_VIRT_PPI], NULL);
329     release_irq(timer_irq[TIMER_PHYS_NONSECURE_PPI], NULL);
330 }
331 
332 /* Wait a set number of microseconds */
udelay(unsigned long usecs)333 void udelay(unsigned long usecs)
334 {
335     s_time_t deadline = get_s_time() + 1000 * (s_time_t) usecs;
336     while ( get_s_time() - deadline < 0 )
337         ;
338     dsb(sy);
339     isb();
340 }
341 
342 /* VCPU PV timers. */
send_timer_event(struct vcpu * v)343 void send_timer_event(struct vcpu *v)
344 {
345     send_guest_vcpu_virq(v, VIRQ_TIMER);
346 }
347 
348 /* VCPU PV clock. */
update_vcpu_system_time(struct vcpu * v)349 void update_vcpu_system_time(struct vcpu *v)
350 {
351     /* XXX update shared_info->wc_* */
352 }
353 
domain_set_time_offset(struct domain * d,int64_t time_offset_seconds)354 void domain_set_time_offset(struct domain *d, int64_t time_offset_seconds)
355 {
356     d->time_offset.seconds = time_offset_seconds;
357     d->time_offset.set = true;
358     /* XXX update guest visible wallclock time */
359 }
360 
cpu_time_callback(struct notifier_block * nfb,unsigned long action,void * hcpu)361 static int cpu_time_callback(struct notifier_block *nfb,
362                              unsigned long action,
363                              void *hcpu)
364 {
365     switch ( action )
366     {
367     case CPU_DYING:
368         deinit_timer_interrupt();
369         break;
370     default:
371         break;
372     }
373 
374     return NOTIFY_DONE;
375 }
376 
377 static struct notifier_block cpu_time_nfb = {
378     .notifier_call = cpu_time_callback,
379 };
380 
cpu_time_notifier_init(void)381 static int __init cpu_time_notifier_init(void)
382 {
383     register_cpu_notifier(&cpu_time_nfb);
384 
385     return 0;
386 }
387 __initcall(cpu_time_notifier_init);
388 
389 /*
390  * Local variables:
391  * mode: C
392  * c-file-style: "BSD"
393  * c-basic-offset: 4
394  * indent-tabs-mode: nil
395  * End:
396  */
397