Skip to content

Commit be146c9

Browse files
authored
Merge pull request #29 from yanjiew1/gicv2
Add support for arm64 GICv2 host
2 parents 1e187fb + cda347e commit be146c9

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

src/arch/arm64/vm-arch.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
#define ARM_GIC_DIST_BASE ARM_GIC_BASE
3030
#define ARM_GIC_DIST_SIZE KVM_VGIC_V3_DIST_SIZE
3131

32-
#define ARM_GIC_REDIST_BASE (ARM_GIC_DIST_BASE + ARM_GIC_DIST_SIZE)
33-
#define ARM_GIC_REDIST_SIZE KVM_VGIC_V3_REDIST_SIZE
32+
#define ARM_GIC_REDIST_CPUI_BASE (ARM_GIC_DIST_BASE + ARM_GIC_DIST_SIZE)
33+
#define ARM_GIC_REDIST_CPUI_SIZE KVM_VGIC_V3_REDIST_SIZE
3434

3535
#define ARM_PCI_CFG_BASE 0x40000000UL
3636
#define ARM_PCI_CFG_SIZE (1UL << 16)

src/arch/arm64/vm.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@
1313
#include "vm-arch.h"
1414
#include "vm.h"
1515

16+
#define IRQCHIP_TYPE_GIC_V2 1
17+
#define IRQCHIP_TYPE_GIC_V3 2
18+
1619
typedef struct {
1720
uint64_t entry;
1821
size_t initrdsz;
1922
int gic_fd;
23+
int gic_type;
2024

2125
/* This device is a bridge between mmio_bus and io_bus*/
2226
struct dev iodev;
@@ -28,7 +32,7 @@ static int create_irqchip(vm_t *v)
2832
{
2933
vm_arch_priv_t *priv = (vm_arch_priv_t *) v->priv;
3034
uint64_t dist_addr = ARM_GIC_DIST_BASE;
31-
uint64_t redist_addr = ARM_GIC_REDIST_BASE;
35+
uint64_t redist_cpui_addr = ARM_GIC_REDIST_CPUI_BASE;
3236

3337
struct kvm_create_device device = {
3438
.type = KVM_DEV_TYPE_ARM_VGIC_V3,
@@ -38,16 +42,22 @@ static int create_irqchip(vm_t *v)
3842
.attr = KVM_VGIC_V3_ADDR_TYPE_DIST,
3943
.addr = (uint64_t) &dist_addr,
4044
};
41-
struct kvm_device_attr redist_attr = {
45+
struct kvm_device_attr redist_cpui_attr = {
4246
.group = KVM_DEV_ARM_VGIC_GRP_ADDR,
4347
.attr = KVM_VGIC_V3_ADDR_TYPE_REDIST,
44-
.addr = (uint64_t) &redist_addr,
48+
.addr = (uint64_t) &redist_cpui_addr,
4549
};
4650

51+
priv->gic_type = IRQCHIP_TYPE_GIC_V3;
4752
if (ioctl(v->vm_fd, KVM_CREATE_DEVICE, &device) < 0) {
48-
throw_err("Failed to create GICv3 chip.\n");
49-
fprintf(stderr, "Your system may not support GICv3.\n");
50-
return -1;
53+
/* Try to create GICv2 chip */
54+
device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
55+
if (ioctl(v->vm_fd, KVM_CREATE_DEVICE, &device) < 0)
56+
return throw_err("Failed to create IRQ chip\n");
57+
58+
dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST;
59+
redist_cpui_attr.attr = KVM_VGIC_V2_ADDR_TYPE_CPU;
60+
priv->gic_type = IRQCHIP_TYPE_GIC_V2;
5161
}
5262

5363
priv->gic_fd = device.fd;
@@ -56,9 +66,11 @@ static int create_irqchip(vm_t *v)
5666
return throw_err(
5767
"Failed to set the address of the distributor of GIC.\n");
5868

59-
if (ioctl(priv->gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr) < 0)
60-
return throw_err(
61-
"Failed to set the address of the redistributor of GIC.\n");
69+
if (ioctl(priv->gic_fd, KVM_SET_DEVICE_ATTR, &redist_cpui_attr) < 0)
70+
return throw_err("Failed to set the address of the %s of GIC.\n",
71+
device.type == KVM_DEV_TYPE_ARM_VGIC_V3
72+
? "redistributer"
73+
: "CPU interface");
6274

6375
return 0;
6476
}
@@ -311,8 +323,11 @@ static int generate_fdt(vm_t *v)
311323
__FDT(begin_node, "intr");
312324
uint64_t gic_reg[] = {
313325
cpu_to_fdt64(ARM_GIC_DIST_BASE), cpu_to_fdt64(ARM_GIC_DIST_SIZE),
314-
cpu_to_fdt64(ARM_GIC_REDIST_BASE), cpu_to_fdt64(ARM_GIC_REDIST_SIZE)};
315-
__FDT(property_string, "compatible", "arm,gic-v3");
326+
cpu_to_fdt64(ARM_GIC_REDIST_CPUI_BASE), cpu_to_fdt64(ARM_GIC_REDIST_CPUI_SIZE)};
327+
if (priv->gic_type == IRQCHIP_TYPE_GIC_V3)
328+
__FDT(property_string, "compatible", "arm,gic-v3");
329+
else
330+
__FDT(property_string, "compatible", "arm,cortex-a15-gic");
316331
__FDT(property_cell, "#interrupt-cells", 3);
317332
__FDT(property, "interrupt-controller", NULL, 0);
318333
__FDT(property, "reg", &gic_reg, sizeof(gic_reg));

0 commit comments

Comments
 (0)