@@ -358,8 +358,11 @@ void vtd_init(void)
vtd_dump_init_info();
vtd_gcmd_or(VTD_GCMD_QI); /* Enable QI */
- vtd_setup_root_table();
vtd_setup_ir_table();
- vtd_gcmd_or(VTD_GCMD_DMAR); /* Enable DMAR */
vtd_gcmd_or(VTD_GCMD_IR); /* Enable IR */
+
+ if(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW){
+ vtd_setup_root_table();
+ vtd_gcmd_or(VTD_GCMD_DMAR); /* Enable DMAR */
+ }
}
@@ -100,7 +100,8 @@
#define VTD_CAP_SAGAW_39bit (0x2ULL << VTD_CAP_SAGAW_SHIFT)
/* 48-bit AGAW, 4-level page-table */
#define VTD_CAP_SAGAW_48bit (0x4ULL << VTD_CAP_SAGAW_SHIFT)
-#define VTD_CAP_SAGAW VTD_CAP_SAGAW_39bit
+/* All SAGAW bits */
+#define VTD_CAP_SAGAW (0x1FULL << VTD_CAP_SAGAW_SHIFT)
/* Both 1G/2M huge pages */
#define VTD_CAP_SLLPS ((1ULL << 34) | (1ULL << 35))
@@ -140,14 +140,20 @@ int main(int argc, char *argv[])
report(vtd_readl(DMAR_FSTS_REG) == 0, "fault status check");
report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_QI, "QI enablement");
- report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_ROOT, "DMAR table setup");
report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_IR_TABLE, "IR table setup");
- report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_DMAR, "DMAR enablement");
report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_IR, "IR enablement");
- report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW,
+
+ if (vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW) {
+ report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_ROOT, "DMAR table setup");
+ report(vtd_readl(DMAR_GSTS_REG) & VTD_GCMD_DMAR, "DMAR enablement");
+ report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SAGAW_39bit,
"DMAR support 39 bits address width");
- report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SLLPS,
- "DMAR support huge pages");
+ report(vtd_readq(DMAR_CAP_REG) & VTD_CAP_SLLPS,
+ "DMAR support huge pages");
+ } else {
+ printf("DMAR marked as not implemented by machine,"
+ " skipping DMAR setup and tests.\n");
+ }
report_prefix_pop();
@@ -160,7 +166,11 @@ int main(int argc, char *argv[])
} else {
printf("Found EDU device:\n");