summary refs log tree commit diff stats
path: root/hw/i386/acpi-build.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-09-26 19:47:00 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-09-26 19:47:00 +0100
commit7cfdc02dae0d2ff58c897496cfdbbafc0eda0f3f (patch)
tree4ab986d748b8e4f914a388fe449366f9812b0f7d /hw/i386/acpi-build.c
parent3b71ec8516bb50e9a743645bf139571de0b39f61 (diff)
parentfb9f592623b0f9bb82a88d68d7921fb581918ef5 (diff)
downloadfocaccia-qemu-7cfdc02dae0d2ff58c897496cfdbbafc0eda0f3f.tar.gz
focaccia-qemu-7cfdc02dae0d2ff58c897496cfdbbafc0eda0f3f.zip
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio, pc: fixes and features

beginning of guest error handling for virtio devices
amd iommu
pc compat fixes

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Fri 23 Sep 2016 23:02:09 BST
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  hw/i386: AMD IOMMU IVRS table
  hw/i386: Introduce AMD IOMMU
  hw/i386/trace-events: Add AMD IOMMU trace events
  hw/pci: Prepare for AMD IOMMU
  virtio: handle virtqueue_get_head() errors
  virtio: handle virtqueue_num_heads() errors
  virtio: handle virtqueue_read_next_desc() errors
  virtio: use unsigned int for virtqueue_get_avail_bytes() index
  virtio: handle virtqueue_get_avail_bytes() errors
  virtio: handle virtqueue_map_desc() errors
  virtio: migrate vdev->broken flag
  virtio: stop virtqueue processing if device is broken
  virtio: fix stray tab character
  target-i386: turn off CPU.l3-cache only for 2.7 and older machine types
  pc: clean up COMPAT macro chaining
  virtio: add check for descriptor's mapped address
  tests: add /vhost-user/flags-mismatch test
  tests: add a simple /vhost-user/multiqueue test
  tests: add /vhost-user/connect-fail test

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i386/acpi-build.c')
-rw-r--r--hw/i386/acpi-build.c76
1 files changed, 67 insertions, 9 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 433febafdd..c20bc71a67 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -59,7 +59,8 @@
 
 #include "qapi/qmp/qint.h"
 #include "qom/qom-qobject.h"
-#include "hw/i386/x86-iommu.h"
+#include "hw/i386/amd_iommu.h"
+#include "hw/i386/intel_iommu.h"
 
 #include "hw/acpi/ipmi.h"
 
@@ -2562,6 +2563,62 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
     build_header(linker, table_data, (void *)(table_data->data + dmar_start),
                  "DMAR", table_data->len - dmar_start, 1, NULL, NULL);
 }
+/*
+ *   IVRS table as specified in AMD IOMMU Specification v2.62, Section 5.2
+ *   accessible here http://support.amd.com/TechDocs/48882_IOMMU.pdf
+ */
+static void
+build_amd_iommu(GArray *table_data, BIOSLinker *linker)
+{
+    int iommu_start = table_data->len;
+    AMDVIState *s = AMD_IOMMU_DEVICE(x86_iommu_get_default());
+
+    /* IVRS header */
+    acpi_data_push(table_data, sizeof(AcpiTableHeader));
+    /* IVinfo - IO virtualization information common to all
+     * IOMMU units in a system
+     */
+    build_append_int_noprefix(table_data, 40UL << 8/* PASize */, 4);
+    /* reserved */
+    build_append_int_noprefix(table_data, 0, 8);
+
+    /* IVHD definition - type 10h */
+    build_append_int_noprefix(table_data, 0x10, 1);
+    /* virtualization flags */
+    build_append_int_noprefix(table_data,
+                             (1UL << 0) | /* HtTunEn      */
+                             (1UL << 4) | /* iotblSup     */
+                             (1UL << 6) | /* PrefSup      */
+                             (1UL << 7),  /* PPRSup       */
+                             1);
+    /* IVHD length */
+    build_append_int_noprefix(table_data, 0x24, 2);
+    /* DeviceID */
+    build_append_int_noprefix(table_data, s->devid, 2);
+    /* Capability offset */
+    build_append_int_noprefix(table_data, s->capab_offset, 2);
+    /* IOMMU base address */
+    build_append_int_noprefix(table_data, s->mmio.addr, 8);
+    /* PCI Segment Group */
+    build_append_int_noprefix(table_data, 0, 2);
+    /* IOMMU info */
+    build_append_int_noprefix(table_data, 0, 2);
+    /* IOMMU Feature Reporting */
+    build_append_int_noprefix(table_data,
+                             (48UL << 30) | /* HATS   */
+                             (48UL << 28) | /* GATS   */
+                             (1UL << 2),    /* GTSup  */
+                             4);
+    /*
+     *   Type 1 device entry reporting all devices
+     *   These are 4-byte device entries currently reporting the range of
+     *   Refer to Spec - Table 95:IVHD Device Entry Type Codes(4-byte)
+     */
+    build_append_int_noprefix(table_data, 0x0000001, 4);
+
+    build_header(linker, table_data, (void *)(table_data->data + iommu_start),
+                 "IVRS", table_data->len - iommu_start, 1, NULL, NULL);
+}
 
 static GArray *
 build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
@@ -2622,11 +2679,6 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
     return true;
 }
 
-static bool acpi_has_iommu(void)
-{
-    return !!x86_iommu_get_default();
-}
-
 static
 void acpi_build(AcpiBuildTables *tables, MachineState *machine)
 {
@@ -2706,9 +2758,15 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
         acpi_add_table(table_offsets, tables_blob);
         build_mcfg_q35(tables_blob, tables->linker, &mcfg);
     }
-    if (acpi_has_iommu()) {
-        acpi_add_table(table_offsets, tables_blob);
-        build_dmar_q35(tables_blob, tables->linker);
+    if (x86_iommu_get_default()) {
+        IommuType IOMMUType = x86_iommu_get_type();
+        if (IOMMUType == TYPE_AMD) {
+            acpi_add_table(table_offsets, tables_blob);
+            build_amd_iommu(tables_blob, tables->linker);
+        } else if (IOMMUType == TYPE_INTEL) {
+            acpi_add_table(table_offsets, tables_blob);
+            build_dmar_q35(tables_blob, tables->linker);
+        }
     }
     if (pcms->acpi_nvdimm_state.is_enabled) {
         nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,