xref: /kvmtool/arm/timer.c (revision 045fc040c8310948c39b057970342c905f01f6b3)
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_EDGE_RISING),
19 
20 		cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
21 		cpu_to_fdt32(irqs[1]),
22 		cpu_to_fdt32(cpu_mask | IRQ_TYPE_EDGE_RISING),
23 
24 		cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
25 		cpu_to_fdt32(irqs[2]),
26 		cpu_to_fdt32(cpu_mask | IRQ_TYPE_EDGE_RISING),
27 
28 		cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
29 		cpu_to_fdt32(irqs[3]),
30 		cpu_to_fdt32(cpu_mask | IRQ_TYPE_EDGE_RISING),
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