1 #include "kvm/devices.h"
2 #include "kvm/fdt.h"
3 #include "kvm/ioeventfd.h"
4 #include "kvm/ioport.h"
5 #include "kvm/kvm.h"
6 #include "kvm/kvm-cpu.h"
7 #include "kvm/irq.h"
8 #include "kvm/util.h"
9
10 static int aia_fd = -1;
11
12 static u32 aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
13 static struct kvm_device_attr aia_mode_attr = {
14 .group = KVM_DEV_RISCV_AIA_GRP_CONFIG,
15 .attr = KVM_DEV_RISCV_AIA_CONFIG_MODE,
16 };
17
18 static u32 aia_nr_ids = 0;
19 static struct kvm_device_attr aia_nr_ids_attr = {
20 .group = KVM_DEV_RISCV_AIA_GRP_CONFIG,
21 .attr = KVM_DEV_RISCV_AIA_CONFIG_IDS,
22 };
23
24 static u32 aia_nr_sources = 0;
25 static struct kvm_device_attr aia_nr_sources_attr = {
26 .group = KVM_DEV_RISCV_AIA_GRP_CONFIG,
27 .attr = KVM_DEV_RISCV_AIA_CONFIG_SRCS,
28 };
29
30 static u32 aia_hart_bits = 0;
31 static struct kvm_device_attr aia_hart_bits_attr = {
32 .group = KVM_DEV_RISCV_AIA_GRP_CONFIG,
33 .attr = KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
34 };
35
36 static u32 aia_nr_harts = 0;
37
38 #define IRQCHIP_AIA_NR 0
39
40 #define AIA_IMSIC_BASE RISCV_IRQCHIP
41 #define AIA_IMSIC_ADDR(__hart) \
42 (AIA_IMSIC_BASE + (__hart) * KVM_DEV_RISCV_IMSIC_SIZE)
43 #define AIA_IMSIC_SIZE \
44 (aia_nr_harts * KVM_DEV_RISCV_IMSIC_SIZE)
45 #define AIA_APLIC_ADDR \
46 (AIA_IMSIC_BASE + AIA_IMSIC_SIZE)
47
aia__generate_fdt_node(void * fdt,struct kvm * kvm)48 static void aia__generate_fdt_node(void *fdt, struct kvm *kvm)
49 {
50 u32 i;
51 char name[64];
52 u32 reg_cells[4], *irq_cells;
53
54 irq_cells = calloc(aia_nr_harts * 2, sizeof(u32));
55 if (!irq_cells)
56 die("Failed to alloc irq_cells");
57
58 sprintf(name, "imsics@%08x", (u32)AIA_IMSIC_BASE);
59 _FDT(fdt_begin_node(fdt, name));
60 _FDT(fdt_property_string(fdt, "compatible", "riscv,imsics"));
61 reg_cells[0] = 0;
62 reg_cells[1] = cpu_to_fdt32(AIA_IMSIC_BASE);
63 reg_cells[2] = 0;
64 reg_cells[3] = cpu_to_fdt32(AIA_IMSIC_SIZE);
65 _FDT(fdt_property(fdt, "reg", reg_cells, sizeof(reg_cells)));
66 _FDT(fdt_property_cell(fdt, "#interrupt-cells", 0));
67 _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
68 _FDT(fdt_property(fdt, "msi-controller", NULL, 0));
69 _FDT(fdt_property_cell(fdt, "riscv,num-ids", aia_nr_ids));
70 _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_AIA_IMSIC));
71 for (i = 0; i < aia_nr_harts; i++) {
72 irq_cells[2*i + 0] = cpu_to_fdt32(PHANDLE_CPU_INTC_BASE + i);
73 irq_cells[2*i + 1] = cpu_to_fdt32(9);
74 }
75 _FDT(fdt_property(fdt, "interrupts-extended", irq_cells,
76 sizeof(u32) * aia_nr_harts * 2));
77 _FDT(fdt_end_node(fdt));
78
79 free(irq_cells);
80
81 /* Skip APLIC node if we have no interrupt sources */
82 if (!aia_nr_sources)
83 return;
84
85 sprintf(name, "aplic@%08x", (u32)AIA_APLIC_ADDR);
86 _FDT(fdt_begin_node(fdt, name));
87 _FDT(fdt_property_string(fdt, "compatible", "riscv,aplic"));
88 reg_cells[0] = 0;
89 reg_cells[1] = cpu_to_fdt32(AIA_APLIC_ADDR);
90 reg_cells[2] = 0;
91 reg_cells[3] = cpu_to_fdt32(KVM_DEV_RISCV_APLIC_SIZE);
92 _FDT(fdt_property(fdt, "reg", reg_cells, sizeof(reg_cells)));
93 _FDT(fdt_property_cell(fdt, "#interrupt-cells", 2));
94 _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
95 _FDT(fdt_property_cell(fdt, "riscv,num-sources", aia_nr_sources));
96 _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_AIA_APLIC));
97 _FDT(fdt_property_cell(fdt, "msi-parent", PHANDLE_AIA_IMSIC));
98 _FDT(fdt_end_node(fdt));
99 }
100
aia__irq_routing_init(struct kvm * kvm)101 static int aia__irq_routing_init(struct kvm *kvm)
102 {
103 int r;
104 int irqlines = aia_nr_sources + 1;
105
106 /* Skip this if we have no interrupt sources */
107 if (!aia_nr_sources)
108 return 0;
109
110 /*
111 * This describes the default routing that the kernel uses without
112 * any routing explicitly set up via KVM_SET_GSI_ROUTING. So we
113 * don't need to commit these setting right now. The first actual
114 * user (MSI routing) will engage these mappings then.
115 */
116 for (next_gsi = 0; next_gsi < irqlines; next_gsi++) {
117 r = irq__allocate_routing_entry();
118 if (r)
119 return r;
120
121 irq_routing->entries[irq_routing->nr++] =
122 (struct kvm_irq_routing_entry) {
123 .gsi = next_gsi,
124 .type = KVM_IRQ_ROUTING_IRQCHIP,
125 .u.irqchip.irqchip = IRQCHIP_AIA_NR,
126 .u.irqchip.pin = next_gsi,
127 };
128 }
129
130 return 0;
131 }
132
aia__init(struct kvm * kvm)133 static int aia__init(struct kvm *kvm)
134 {
135 int i, ret;
136 u64 aia_addr = 0;
137 struct kvm_device_attr aia_addr_attr = {
138 .group = KVM_DEV_RISCV_AIA_GRP_ADDR,
139 .addr = (u64)(unsigned long)&aia_addr,
140 };
141 struct kvm_device_attr aia_init_attr = {
142 .group = KVM_DEV_RISCV_AIA_GRP_CTRL,
143 .attr = KVM_DEV_RISCV_AIA_CTRL_INIT,
144 };
145
146 /* Setup global device attribute variables */
147 aia_mode_attr.addr = (u64)(unsigned long)&aia_mode;
148 aia_nr_ids_attr.addr = (u64)(unsigned long)&aia_nr_ids;
149 aia_nr_sources_attr.addr = (u64)(unsigned long)&aia_nr_sources;
150 aia_hart_bits_attr.addr = (u64)(unsigned long)&aia_hart_bits;
151
152 /* Do nothing if AIA device not created */
153 if (aia_fd < 0)
154 return 0;
155
156 /* Set/Get AIA device config parameters */
157 ret = ioctl(aia_fd, KVM_GET_DEVICE_ATTR, &aia_mode_attr);
158 if (ret)
159 return ret;
160 ret = ioctl(aia_fd, KVM_GET_DEVICE_ATTR, &aia_nr_ids_attr);
161 if (ret)
162 return ret;
163 aia_nr_sources = irq__get_nr_allocated_lines();
164 ret = ioctl(aia_fd, KVM_SET_DEVICE_ATTR, &aia_nr_sources_attr);
165 if (ret)
166 return ret;
167 aia_hart_bits = fls_long(kvm->nrcpus - 1);
168 ret = ioctl(aia_fd, KVM_SET_DEVICE_ATTR, &aia_hart_bits_attr);
169 if (ret)
170 return ret;
171
172 /* Save number of HARTs for FDT generation */
173 aia_nr_harts = kvm->nrcpus;
174
175 /* Set AIA device addresses */
176 aia_addr = AIA_APLIC_ADDR;
177 aia_addr_attr.attr = KVM_DEV_RISCV_AIA_ADDR_APLIC;
178 ret = ioctl(aia_fd, KVM_SET_DEVICE_ATTR, &aia_addr_attr);
179 if (ret)
180 return ret;
181 for (i = 0; i < kvm->nrcpus; i++) {
182 aia_addr = AIA_IMSIC_ADDR(i);
183 aia_addr_attr.attr = KVM_DEV_RISCV_AIA_ADDR_IMSIC(i);
184 ret = ioctl(aia_fd, KVM_SET_DEVICE_ATTR, &aia_addr_attr);
185 if (ret)
186 return ret;
187 }
188
189 /* Setup default IRQ routing */
190 aia__irq_routing_init(kvm);
191
192 /* Initialize the AIA device */
193 ret = ioctl(aia_fd, KVM_SET_DEVICE_ATTR, &aia_init_attr);
194 if (ret)
195 return ret;
196
197 /* Mark IRQFD as ready */
198 riscv_irqchip_irqfd_ready = true;
199
200 return 0;
201 }
202 late_init(aia__init);
203
aia__create(struct kvm * kvm)204 void aia__create(struct kvm *kvm)
205 {
206 int err;
207 struct kvm_create_device aia_device = {
208 .type = KVM_DEV_TYPE_RISCV_AIA,
209 .flags = 0,
210 };
211
212 if (kvm->cfg.arch.ext_disabled[KVM_RISCV_ISA_EXT_SSAIA])
213 return;
214
215 err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &aia_device);
216 if (err)
217 return;
218 aia_fd = aia_device.fd;
219
220 riscv_irqchip = IRQCHIP_AIA;
221 riscv_irqchip_inkernel = true;
222 riscv_irqchip_trigger = NULL;
223 riscv_irqchip_generate_fdt_node = aia__generate_fdt_node;
224 riscv_irqchip_phandle = PHANDLE_AIA_APLIC;
225 riscv_irqchip_msi_phandle = PHANDLE_AIA_IMSIC;
226 riscv_irqchip_line_sensing = true;
227 }
228