On Sun, Feb 21, 2016 at 9:20 PM, Jan Kiszka <jan.kis...@web.de> wrote: > On 2016-02-21 19:10, David Kiarie wrote: >> Add IVRS table for AMD IOMMU. Generate IVRS or DMAR >> depending on emulated IOMMU >> >> Signed-off-by: David Kiarie <davidkiar...@gmail.com> >> --- >> hw/i386/acpi-build.c | 208 >> +++++++++++++++++++++++++++++++++++++++++--- >> include/hw/acpi/acpi-defs.h | 55 ++++++++++++ >> 2 files changed, 252 insertions(+), 11 deletions(-) >> >> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c >> index 4554eb8..fa1310f 100644 >> --- a/hw/i386/acpi-build.c >> +++ b/hw/i386/acpi-build.c >> @@ -51,6 +51,7 @@ >> #include "hw/pci/pci_bus.h" >> #include "hw/pci-host/q35.h" >> #include "hw/i386/intel_iommu.h" >> +#include "hw/i386/amd_iommu.h" >> #include "hw/timer/hpet.h" >> >> #include "hw/acpi/aml-build.h" >> @@ -121,6 +122,12 @@ typedef struct AcpiBuildPciBusHotplugState { >> bool pcihp_bridge_en; >> } AcpiBuildPciBusHotplugState; >> >> +typedef enum iommu_type { >> + TYPE_AMD, >> + TYPE_INTEL, >> + TYPE_NONE >> +} iommu_type; >> + >> static >> int acpi_add_cpu_info(Object *o, void *opaque) >> { >> @@ -2513,6 +2520,188 @@ build_dmar_q35(GArray *table_data, GArray *linker) >> "DMAR", table_data->len - dmar_start, 1, NULL, NULL); >> } >> >> +static void >> +build_amd_iommu(GArray *table_data, GArray *linker) >> +{ >> + int iommu_start = table_data->len; >> + bool iommu_ambig; >> + >> + AcpiAMDIOMMUIVRS *ivrs; >> + AcpiAMDIOMMUHardwareUnit *iommu; >> + >> + /* IVRS definition */ >> + ivrs = acpi_data_push(table_data, sizeof(*ivrs)); >> + ivrs->revision = cpu_to_le16(ACPI_IOMMU_IVRS_TYPE); >> + ivrs->length = cpu_to_le16((sizeof(*ivrs) + sizeof(*iommu))); >> + ivrs->v_common_info = cpu_to_le64(AMD_IOMMU_HOST_ADDRESS_WIDTH << 8); >> + >> + AMDIOMMUState *s = (AMDIOMMUState *)object_resolve_path_type("", >> + TYPE_AMD_IOMMU_DEVICE, &iommu_ambig); >> + >> + /* IVDB definition - type 10h */ >> + iommu = acpi_data_push(table_data, sizeof(*iommu)); >> + if (!iommu_ambig) { >> + iommu->type = cpu_to_le16(0x10); >> + /* IVHD flags */ >> + iommu->flags = cpu_to_le16(iommu->flags); >> + iommu->flags = cpu_to_le16(IVHD_HT_TUNEN | IVHD_PPRSUP | >> IVHD_IOTLBSUP >> + | IVHD_PREFSUP); >> + iommu->length = cpu_to_le16(sizeof(*iommu)); >> + iommu->device_id = cpu_to_le16(PCI_DEVICE_ID_RD890_IOMMU); >> + iommu->capability_offset = cpu_to_le16(s->capab_offset); >> + iommu->mmio_base = cpu_to_le64(s->mmio.addr); >> + iommu->pci_segment = 0; >> + iommu->interrupt_info = 0; >> + /* EFR features */ >> + iommu->efr_register = cpu_to_le64(IVHD_EFR_GTSUP | IVHD_EFR_HATS >> + | IVHD_EFR_GATS); >> + iommu->efr_register = cpu_to_le64(iommu->efr_register); >> + /* device entries */ >> + memset(iommu->dev_entries, 0, 20); >> + /* Add device flags here >> + * This is are 4-byte device entries currently reporting the range >> of >> + * devices 00h - ffffh; all devices >> + * >> + * Device setting affecting all devices should be made here >> + * >> + * Refer to >> + * (http://developer.amd.com/wordpress/media/2012/10/488821.pdf) >> + * 5.2.2.1 >> + */ >> + iommu->dev_entries[12] = 3; >> + iommu->dev_entries[16] = 4; >> + iommu->dev_entries[17] = 0xff; >> + iommu->dev_entries[18] = 0xff; >> + } >> + >> + build_header(linker, table_data, (void *)(table_data->data + >> iommu_start), >> + "IVRS", table_data->len - iommu_start, 1, NULL); >> +} >> + >> +static iommu_type has_iommu(void) >> +{ >> + bool ambiguous; >> + >> + if (object_resolve_path_type("", TYPE_AMD_IOMMU_DEVICE, &ambiguous) >> + && !ambiguous) >> + return TYPE_AMD; >> + else if (object_resolve_path_type("", TYPE_INTEL_IOMMU_DEVICE, >> &ambiguous) >> + && !ambiguous) >> + return TYPE_INTEL; >> + else >> + return TYPE_NONE; >> +} >> + >> +static void >> +build_dsdt(GArray *table_data, GArray *linker, >> + AcpiPmInfo *pm, AcpiMiscInfo *misc) >> +{ >> + Aml *dsdt, *sb_scope, *scope, *dev, *method, *field; >> + MachineState *machine = MACHINE(qdev_get_machine()); >> + uint32_t nr_mem = machine->ram_slots; >> + >> + dsdt = init_aml_allocator(); >> + >> + /* Reserve space for header */ >> + acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader)); >> + >> + build_dbg_aml(dsdt); >> + if (misc->is_piix4) { >> + sb_scope = aml_scope("_SB"); >> + dev = aml_device("PCI0"); >> + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); >> + aml_append(dev, aml_name_decl("_ADR", aml_int(0))); >> + aml_append(dev, aml_name_decl("_UID", aml_int(1))); >> + aml_append(sb_scope, dev); >> + aml_append(dsdt, sb_scope); >> + >> + build_hpet_aml(dsdt); >> + build_piix4_pm(dsdt); >> + build_piix4_isa_bridge(dsdt); >> + build_isa_devices_aml(dsdt); >> + build_piix4_pci_hotplug(dsdt); >> + build_piix4_pci0_int(dsdt); >> + } else { >> + sb_scope = aml_scope("_SB"); >> + aml_append(sb_scope, >> + aml_operation_region("PCST", AML_SYSTEM_IO, 0xae00, 0x0c)); >> + aml_append(sb_scope, >> + aml_operation_region("PCSB", AML_SYSTEM_IO, 0xae0c, 0x01)); >> + field = aml_field("PCSB", AML_ANY_ACC, AML_NOLOCK, >> AML_WRITE_AS_ZEROS); >> + aml_append(field, aml_named_field("PCIB", 8)); >> + aml_append(sb_scope, field); >> + aml_append(dsdt, sb_scope); >> + >> + sb_scope = aml_scope("_SB"); >> + dev = aml_device("PCI0"); >> + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); >> + aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); >> + aml_append(dev, aml_name_decl("_ADR", aml_int(0))); >> + aml_append(dev, aml_name_decl("_UID", aml_int(1))); >> + aml_append(dev, aml_name_decl("SUPP", aml_int(0))); >> + aml_append(dev, aml_name_decl("CTRL", aml_int(0))); >> + aml_append(dev, build_q35_osc_method()); >> + aml_append(sb_scope, dev); >> + aml_append(dsdt, sb_scope); >> + >> + build_hpet_aml(dsdt); >> + build_q35_isa_bridge(dsdt); >> + build_isa_devices_aml(dsdt); >> + build_q35_pci0_int(dsdt); >> + } >> + >> + build_cpu_hotplug_aml(dsdt); >> + build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base, >> + pm->mem_hp_io_len); >> + >> + scope = aml_scope("_GPE"); >> + { >> + aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); >> + >> + aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED)); >> + >> + if (misc->is_piix4) { >> + method = aml_method("_E01", 0, AML_NOTSERIALIZED); >> + aml_append(method, >> + aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF)); >> + aml_append(method, aml_call0("\\_SB.PCI0.PCNT")); >> + aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK"))); >> + aml_append(scope, method); >> + } else { >> + aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED)); >> + } >> + >> + method = aml_method("_E02", 0, AML_NOTSERIALIZED); >> + aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD)); >> + aml_append(scope, method); >> + >> + method = aml_method("_E03", 0, AML_NOTSERIALIZED); >> + aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH)); >> + aml_append(scope, method); >> + >> + aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED)); >> + aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED)); >> + } >> + aml_append(dsdt, scope); >> + >> + /* copy AML table into ACPI tables blob and patch header there */ >> + g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); >> + build_header(linker, table_data, >> + (void *)(table_data->data + table_data->len - dsdt->buf->len), >> + "DSDT", dsdt->buf->len, 1, NULL); > > Grabbed an old version by accident? This one still cannot build over > current master (c3bce9d5f9).
heh, no, I sent the current version. Current workflow; Fix code, test , rebase on master (and blow up everything), send. Am replying with the correct patch, in case someone wants to test. > > In fact, there are more build error with this file. Please check > carefully before posting. > > Jan > >