1 #include "kvm/fdt.h"
2 #include "kvm/kvm.h"
3 #include "kvm/kvm-cpu.h"
4 #include "kvm/util.h"
5
6 #include "arm-common/gic.h"
7 #include "arm-common/timer.h"
8
timer__generate_fdt_nodes(void * fdt,struct kvm * kvm,int * irqs)9 void timer__generate_fdt_nodes(void *fdt, struct kvm *kvm, int *irqs)
10 {
11 const char compatible[] = "arm,armv8-timer\0arm,armv7-timer";
12 u32 cpu_mask = gic__get_fdt_irq_cpumask(kvm);
13 u32 irq_prop[] = {
14 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
15 cpu_to_fdt32(irqs[0]),
16 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW),
17
18 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
19 cpu_to_fdt32(irqs[1]),
20 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW),
21
22 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
23 cpu_to_fdt32(irqs[2]),
24 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW),
25
26 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
27 cpu_to_fdt32(irqs[3]),
28 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW),
29 };
30
31 _FDT(fdt_begin_node(fdt, "timer"));
32 _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible)));
33 _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
34 _FDT(fdt_property(fdt, "always-on", NULL, 0));
35 if (kvm->cfg.arch.force_cntfrq > 0)
36 _FDT(fdt_property_cell(fdt, "clock-frequency", kvm->cfg.arch.force_cntfrq));
37 _FDT(fdt_end_node(fdt));
38 }
39
40