/* IOMMU info */
build_append_int_noprefix(table_data, 0, 2);
/* IOMMU Attributes */
- build_append_int_noprefix(table_data, 0, 4);
+ if (!s->iommu.dma_translation) {
+ build_append_int_noprefix(table_data, (1UL << 0) /* HATDis */, 4);
+ } else {
+ build_append_int_noprefix(table_data, 0, 4);
+ }
/* EFR Register Image */
build_append_int_noprefix(table_data,
amdvi_extended_feature_register(s),
if (s->xtsup) {
feature |= AMDVI_FEATURE_XT;
}
+ if (!s->iommu.dma_translation) {
+ feature |= AMDVI_HATS_MODE_RESERVED;
+ }
return feature;
}
static bool amdvi_validate_dte(AMDVIState *s, uint16_t devid,
uint64_t *dte)
{
+
+ uint64_t root;
+
if ((dte[0] & AMDVI_DTE_QUAD0_RESERVED) ||
(dte[1] & AMDVI_DTE_QUAD1_RESERVED) ||
(dte[2] & AMDVI_DTE_QUAD2_RESERVED) ||
return false;
}
+ /*
+ * 1 = Host Address Translation is not supported. Value in MMIO Offset
+ * 0030h[HATS] is not meaningful. A non-zero host page table root pointer
+ * in the DTE would result in an ILLEGAL_DEV_TABLE_ENTRY event.
+ */
+ root = (dte[0] & AMDVI_DEV_PT_ROOT_MASK) >> 12;
+ if (root && !s->iommu.dma_translation) {
+ amdvi_log_illegaldevtab_error(s, devid,
+ s->devtab +
+ devid * AMDVI_DEVTAB_ENTRY_SIZE, 0);
+ return false;
+ }
+
return true;
}
/* AMDVI paging mode */
#define AMDVI_GATS_MODE (2ULL << 12)
#define AMDVI_HATS_MODE (2ULL << 10)
+#define AMDVI_HATS_MODE_RESERVED (3ULL << 10)
/* Page Table format */