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 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 13 u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \ 14 & GIC_FDT_IRQ_PPI_CPU_MASK; 15 u32 irq_prop[] = { 16 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 17 cpu_to_fdt32(irqs[0]), 18 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW), 19 20 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 21 cpu_to_fdt32(irqs[1]), 22 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW), 23 24 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 25 cpu_to_fdt32(irqs[2]), 26 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW), 27 28 cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 29 cpu_to_fdt32(irqs[3]), 30 cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_LOW), 31 }; 32 33 _FDT(fdt_begin_node(fdt, "timer")); 34 _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible))); 35 _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); 36 _FDT(fdt_property(fdt, "always-on", NULL, 0)); 37 if (kvm->cfg.arch.force_cntfrq > 0) 38 _FDT(fdt_property_cell(fdt, "clock-frequency", kvm->cfg.arch.force_cntfrq)); 39 _FDT(fdt_end_node(fdt)); 40 } 41 42