Browse Source

hw/arm/smmuv3-accel: Introduce smmuv3 accel device

Set up dedicated PCIIOMMUOps for the accel SMMUv3, since it will need
different callback handling in upcoming patches. This also adds a
CONFIG_ARM_SMMUV3_ACCEL build option so the feature can be disabled
at compile time. Because we now include CONFIG_DEVICES in the header to
check for ARM_SMMUV3_ACCEL, the meson file entry for smmuv3.c needs to
be changed to arm_ss.add.

The “accel” property isn’t user visible yet and it will be introduced in
a later patch once all the supporting pieces are ready.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Tested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Message-id: 20260126104342.253965-6-skolothumtho@nvidia.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
pull/319/head
Shameer Kolothum 2 months ago
committed by Peter Maydell
parent
commit
79fcbec80a
  1. 5
      hw/arm/Kconfig
  2. 3
      hw/arm/meson.build
  3. 59
      hw/arm/smmuv3-accel.c
  4. 27
      hw/arm/smmuv3-accel.h
  5. 5
      hw/arm/smmuv3.c
  6. 3
      include/hw/arm/smmuv3.h

5
hw/arm/Kconfig

@ -626,8 +626,13 @@ config FSL_IMX8MP_EVK
depends on TCG
select FSL_IMX8MP
config ARM_SMMUV3_ACCEL
bool
depends on ARM_SMMUV3
config ARM_SMMUV3
bool
select ARM_SMMUV3_ACCEL if IOMMUFD
config FSL_IMX6UL
bool

3
hw/arm/meson.build

@ -84,7 +84,8 @@ arm_common_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP', if_true: files('fsl-imx8mp.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c'))
arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
arm_ss.add(when: 'CONFIG_ARM_SMMUV3_ACCEL', if_true: files('smmuv3-accel.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
arm_common_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
arm_common_ss.add(when: 'CONFIG_XEN', if_true: files(

59
hw/arm/smmuv3-accel.c

@ -0,0 +1,59 @@
/*
* Copyright (c) 2025 Huawei Technologies R & D (UK) Ltd
* Copyright (C) 2025 NVIDIA
* Written by Nicolin Chen, Shameer Kolothum
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "hw/arm/smmuv3.h"
#include "smmuv3-accel.h"
static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus,
PCIBus *bus, int devfn)
{
SMMUDevice *sdev = sbus->pbdev[devfn];
SMMUv3AccelDevice *accel_dev;
if (sdev) {
return container_of(sdev, SMMUv3AccelDevice, sdev);
}
accel_dev = g_new0(SMMUv3AccelDevice, 1);
sdev = &accel_dev->sdev;
sbus->pbdev[devfn] = sdev;
smmu_init_sdev(bs, sdev, bus, devfn);
return accel_dev;
}
/*
* Find or add an address space for the given PCI device.
*
* If a device matching @bus and @devfn already exists, return its
* corresponding address space. Otherwise, create a new device entry
* and initialize address space for it.
*/
static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque,
int devfn)
{
SMMUState *bs = opaque;
SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
SMMUDevice *sdev = &accel_dev->sdev;
return &sdev->as;
}
static const PCIIOMMUOps smmuv3_accel_ops = {
.get_address_space = smmuv3_accel_find_add_as,
};
void smmuv3_accel_init(SMMUv3State *s)
{
SMMUState *bs = ARM_SMMU(s);
bs->iommu_ops = &smmuv3_accel_ops;
}

27
hw/arm/smmuv3-accel.h

@ -0,0 +1,27 @@
/*
* Copyright (c) 2025 Huawei Technologies R & D (UK) Ltd
* Copyright (C) 2025 NVIDIA
* Written by Nicolin Chen, Shameer Kolothum
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef HW_ARM_SMMUV3_ACCEL_H
#define HW_ARM_SMMUV3_ACCEL_H
#include "hw/arm/smmu-common.h"
#include CONFIG_DEVICES
typedef struct SMMUv3AccelDevice {
SMMUDevice sdev;
} SMMUv3AccelDevice;
#ifdef CONFIG_ARM_SMMUV3_ACCEL
void smmuv3_accel_init(SMMUv3State *s);
#else
static inline void smmuv3_accel_init(SMMUv3State *s)
{
}
#endif
#endif /* HW_ARM_SMMUV3_ACCEL_H */

5
hw/arm/smmuv3.c

@ -32,6 +32,7 @@
#include "qapi/error.h"
#include "hw/arm/smmuv3.h"
#include "smmuv3-accel.h"
#include "smmuv3-internal.h"
#include "smmu-internal.h"
@ -1882,6 +1883,10 @@ static void smmu_realize(DeviceState *d, Error **errp)
SysBusDevice *dev = SYS_BUS_DEVICE(d);
Error *local_err = NULL;
if (s->accel) {
smmuv3_accel_init(s);
}
c->parent_realize(d, &local_err);
if (local_err) {
error_propagate(errp, local_err);

3
include/hw/arm/smmuv3.h

@ -63,6 +63,9 @@ struct SMMUv3State {
qemu_irq irq[4];
QemuMutex mutex;
char *stage;
/* SMMU has HW accelerator support for nested S1 + s2 */
bool accel;
};
typedef enum {

Loading…
Cancel
Save