From 79bb851b07ba30d7b09e3177ecd9a78b200bedb9 Mon Sep 17 00:00:00 2001 From: jmcneill Date: Wed, 28 Nov 2018 22:54:11 +0000 Subject: [PATCH] Allow non-power of 2 counts, and support alloc/release/alloc patterns for a device as long as the ITT size is sufficient --- sys/arch/arm/cortex/gicv3_its.c | 21 ++++++++++++--------- sys/arch/arm/cortex/gicv3_its.h | 3 ++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sys/arch/arm/cortex/gicv3_its.c b/sys/arch/arm/cortex/gicv3_its.c index f53487f99d1a..50a625f3c6ce 100644 --- a/sys/arch/arm/cortex/gicv3_its.c +++ b/sys/arch/arm/cortex/gicv3_its.c @@ -1,4 +1,4 @@ -/* $NetBSD: gicv3_its.c,v 1.8 2018/11/24 15:40:57 skrll Exp $ */ +/* $NetBSD: gicv3_its.c,v 1.9 2018/11/28 22:54:11 jmcneill Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #define _INTR_PRIVATE #include -__KERNEL_RCSID(0, "$NetBSD: gicv3_its.c,v 1.8 2018/11/24 15:40:57 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gicv3_its.c,v 1.9 2018/11/28 22:54:11 jmcneill Exp $"); #include #include @@ -293,22 +293,25 @@ static int gicv3_its_device_map(struct gicv3_its *its, uint32_t devid, u_int count) { struct gicv3_its_device *dev; + u_int vectors; - LIST_FOREACH(dev, &its->its_devices, dev_list) - if (dev->dev_id == devid) - return EEXIST; - - const u_int vectors = MAX(2, count); - if (!powerof2(vectors)) - return EINVAL; + vectors = MAX(2, count); + while (!powerof2(vectors)) + vectors++; const uint64_t typer = gits_read_8(its, GITS_TYPER); const u_int id_bits = __SHIFTOUT(typer, GITS_TYPER_ID_bits) + 1; const u_int itt_entry_size = __SHIFTOUT(typer, GITS_TYPER_ITT_entry_size) + 1; const u_int itt_size = roundup(vectors * itt_entry_size, GITS_ITT_ALIGN); + LIST_FOREACH(dev, &its->its_devices, dev_list) + if (dev->dev_id == devid) { + return itt_size <= dev->dev_size ? 0 : EEXIST; + } + dev = kmem_alloc(sizeof(*dev), KM_SLEEP); dev->dev_id = devid; + dev->dev_size = itt_size; gicv3_dma_alloc(its->its_gic, &dev->dev_itt, itt_size, GITS_ITT_ALIGN); LIST_INSERT_HEAD(&its->its_devices, dev, dev_list); diff --git a/sys/arch/arm/cortex/gicv3_its.h b/sys/arch/arm/cortex/gicv3_its.h index c5f1fa2beb12..2a1e0c4234fc 100644 --- a/sys/arch/arm/cortex/gicv3_its.h +++ b/sys/arch/arm/cortex/gicv3_its.h @@ -1,4 +1,4 @@ -/* $NetBSD: gicv3_its.h,v 1.3 2018/11/24 22:08:53 jakllsch Exp $ */ +/* $NetBSD: gicv3_its.h,v 1.4 2018/11/28 22:54:11 jmcneill Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -40,6 +40,7 @@ struct gicv3_its_device { uint32_t dev_id; + u_int dev_size; struct gicv3_dma dev_itt; LIST_ENTRY(gicv3_its_device) dev_list;