| 1 | /* |
| 2 | * Copyright (c) 2025 Huawei Technologies R & D (UK) Ltd |
| 3 | * Copyright (C) 2025 NVIDIA |
| 4 | * Written by Nicolin Chen, Shameer Kolothum |
| 5 | * |
| 6 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 7 | */ |
| 8 | |
| 9 | #ifndef HW_ARM_SMMUV3_ACCEL_H |
| 10 | #define HW_ARM_SMMUV3_ACCEL_H |
| 11 | |
| 12 | #include "hw/arm/smmu-common.h" |
| 13 | #include "hw/arm/smmuv3.h" |
| 14 | #include "system/iommufd.h" |
| 15 | #ifdef CONFIG_LINUX |
| 16 | #include <linux/iommufd.h> |
| 17 | #endif |
| 18 | |
| 19 | typedef enum SMMUv3AccelCmdqvType { |
| 20 | SMMUV3_CMDQV_NONE = 0, |
| 21 | SMMUV3_CMDQV_TEGRA241, |
| 22 | } SMMUv3AccelCmdqvType; |
| 23 | |
| 24 | /* |
| 25 | * CMDQ-Virtualization (CMDQV) hardware support, extends the SMMUv3 to |
| 26 | * support multiple VCMDQs with virtualization capabilities. |
| 27 | * CMDQV specific behavior is factored behind this ops interface. |
| 28 | */ |
| 29 | typedef struct SMMUv3AccelCmdqvOps { |
| 30 | /** |
| 31 | * @probe: Mandatory. Vendor-specific device probing. |
| 32 | */ |
| 33 | bool (*probe)(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev, Error **errp); |
| 34 | /** |
| 35 | * @init: Optional callback. Initialize CMDQV hardware. |
| 36 | */ |
| 37 | bool (*init)(SMMUv3State *s, Error **errp); |
| 38 | /** |
| 39 | * @alloc_viommu: Mandatory. Allocate CMDQV viommu resources. |
| 40 | */ |
| 41 | bool (*alloc_viommu)(SMMUv3State *s, |
| 42 | HostIOMMUDeviceIOMMUFD *idev, |
| 43 | uint32_t *out_viommu_id, |
| 44 | Error **errp); |
| 45 | /** |
| 46 | * @free_viommu: Optional callback. Free CMDQV viommu resources. |
| 47 | * If NULL, the viommu_id is freed directly via iommufd_backend_free_id(). |
| 48 | */ |
| 49 | void (*free_viommu)(SMMUv3State *s); |
| 50 | /** |
| 51 | * @get_type: Optional callback. Return the CMDQV implementation type. |
| 52 | */ |
| 53 | SMMUv3AccelCmdqvType (*get_type)(void); |
| 54 | /** |
| 55 | * @reset: Optional callback. Reset CMDQV state. |
| 56 | */ |
| 57 | void (*reset)(SMMUv3State *s); |
| 58 | } SMMUv3AccelCmdqvOps; |
| 59 | |
| 60 | /* |
| 61 | * Represents an accelerated SMMU instance backed by an iommufd vIOMMU object. |
| 62 | * Holds bypass and abort proxy HWPT IDs used for device attachment. |
| 63 | */ |
| 64 | typedef struct SMMUv3AccelState { |
| 65 | IOMMUFDViommu *viommu; |
| 66 | IOMMUFDVeventq *veventq; |
| 67 | uint32_t bypass_hwpt_id; |
| 68 | uint32_t abort_hwpt_id; |
| 69 | QLIST_HEAD(, SMMUv3AccelDevice) device_list; |
| 70 | bool auto_mode; |
| 71 | bool auto_finalised; |
| 72 | const SMMUv3AccelCmdqvOps *cmdqv_ops; |
| 73 | void *cmdqv; /* vendor specific CMDQV state */ |
| 74 | } SMMUv3AccelState; |
| 75 | |
| 76 | typedef struct SMMUS1Hwpt { |
| 77 | uint32_t hwpt_id; |
| 78 | } SMMUS1Hwpt; |
| 79 | |
| 80 | typedef struct SMMUv3AccelDevice { |
| 81 | SMMUDevice sdev; |
| 82 | HostIOMMUDeviceIOMMUFD *hiodi; |
| 83 | SMMUS1Hwpt *s1_hwpt; |
| 84 | IOMMUFDVdev *vdev; |
| 85 | QLIST_ENTRY(SMMUv3AccelDevice) next; |
| 86 | SMMUv3AccelState *s_accel; |
| 87 | Error *unplug_blocker; /* set when CMDQV is active to block hot-unplug */ |
| 88 | } SMMUv3AccelDevice; |
| 89 | |
| 90 | bool smmuv3_accel_init(SMMUv3State *s, Error **errp); |
| 91 | bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid, |
| 92 | Error **errp); |
| 93 | bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range, |
| 94 | Error **errp); |
| 95 | bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp); |
| 96 | bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev, |
| 97 | Error **errp); |
| 98 | void smmuv3_accel_idr_override(SMMUv3State *s); |
| 99 | bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp); |
| 100 | int smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type, |
| 101 | void *buf, size_t size, Error **errp); |
| 102 | void smmuv3_accel_reset(SMMUv3State *s); |
| 103 | SMMUv3AccelCmdqvType smmuv3_accel_cmdqv_type(Object *obj); |
| 104 | |
| 105 | #endif /* HW_ARM_SMMUV3_ACCEL_H */ |