#include "hw/arm/smmuv3.h"
#include "smmuv3-internal.h"
+#include "smmu-internal.h"
/**
* smmuv3_trigger_irq - pulse @irq if enabled and update
}
}
+static gboolean
+smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
+{
+ SMMUDevice *sdev = (SMMUDevice *)key;
+ uint32_t sid = smmu_get_sid(sdev);
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
+
+ if (sid < sid_range->start || sid > sid_range->end) {
+ return false;
+ }
+ trace_smmuv3_config_cache_inv(sid);
+ return true;
+}
+
static int smmuv3_cmdq_consume(SMMUv3State *s)
{
SMMUState *bs = ARM_SMMU(s);
}
case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
{
- uint32_t start = CMD_SID(&cmd), end, i;
+ uint32_t start = CMD_SID(&cmd);
uint8_t range = CMD_STE_RANGE(&cmd);
+ uint64_t end = start + (1ULL << (range + 1)) - 1;
+ SMMUSIDRange sid_range = {start, end};
if (CMD_SSEC(&cmd)) {
cmd_error = SMMU_CERROR_ILL;
break;
}
-
- end = start + (1 << (range + 1)) - 1;
trace_smmuv3_cmdq_cfgi_ste_range(start, end);
-
- for (i = start; i <= end; i++) {
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, i);
- SMMUDevice *sdev;
-
- if (!mr) {
- continue;
- }
- sdev = container_of(mr, SMMUDevice, iommu);
- smmuv3_flush_config(sdev);
- }
+ g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
+ &sid_range);
break;
}
case SMMU_CMD_CFGI_CD: