Apollo Lake needs to generate a few more table types. Add support for
these into the x86 ACPI code.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 arch/x86/lib/acpi_table.c | 115 ++++++++++++++++++++++++++++++++++++++
 include/acpi_table.h      |  37 ++++++++++++
 2 files changed, 152 insertions(+)

diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index f12344de50..886960a5fa 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -450,6 +450,121 @@ void acpi_create_ssdt(struct acpi_ctx *ctx, struct 
acpi_table_header *ssdt,
        ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
 }
 
+void acpi_fadt_common(struct acpi_fadt *fadt, struct acpi_facs *facs,
+                     void *dsdt)
+{
+       struct acpi_table_header *header = &fadt->header;
+
+       memset((void *)fadt, '\0', sizeof(struct acpi_fadt));
+
+       acpi_fill_header(header, "FACP");
+       header->length = sizeof(struct acpi_fadt);
+       header->revision = 4;
+       memcpy(header->oem_id, OEM_ID, 6);
+       memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+       memcpy(header->aslc_id, ASLC_ID, 4);
+       header->aslc_revision = 1;
+
+       fadt->firmware_ctrl = (unsigned long)facs;
+       fadt->dsdt = (unsigned long)dsdt;
+
+       fadt->x_firmware_ctl_l = (unsigned long)facs;
+       fadt->x_firmware_ctl_h = 0;
+       fadt->x_dsdt_l = (unsigned long)dsdt;
+       fadt->x_dsdt_h = 0;
+
+       fadt->preferred_pm_profile = ACPI_PM_MOBILE;
+
+       /* Use ACPI 3.0 revision */
+       fadt->header.revision = 4;
+}
+
+int acpi_create_dmar_drhd(struct acpi_ctx *ctx, uint flags, uint segment,
+                         u64 bar)
+{
+       struct dmar_entry *drhd = ctx->current;
+
+       memset(drhd, 0, sizeof(*drhd));
+       drhd->type = DMAR_DRHD;
+       drhd->length = sizeof(*drhd); /* will be fixed up later */
+       drhd->flags = flags;
+       drhd->segment = segment;
+       drhd->bar = bar;
+       acpi_inc(ctx, drhd->length);
+
+       return 0;
+}
+
+int acpi_create_dmar_rmrr(struct acpi_ctx *ctx, uint segment, u64 bar,
+                         u64 limit)
+{
+       struct dmar_rmrr_entry *rmrr = ctx->current;
+
+       memset(rmrr, 0, sizeof(*rmrr));
+       rmrr->type = DMAR_RMRR;
+       rmrr->length = sizeof(*rmrr); /* will be fixed up later */
+       rmrr->segment = segment;
+       rmrr->bar = bar;
+       rmrr->limit = limit;
+       acpi_inc(ctx, rmrr->length);
+
+       return 0;
+}
+
+void acpi_dmar_drhd_fixup(struct acpi_ctx *ctx, void *base)
+{
+       struct dmar_entry *drhd = base;
+
+       drhd->length = ctx->current - base;
+}
+
+void acpi_dmar_rmrr_fixup(struct acpi_ctx *ctx, void *base)
+{
+       struct dmar_rmrr_entry *rmrr = base;
+
+       rmrr->length = ctx->current - base;
+}
+
+static int acpi_create_dmar_ds(struct acpi_ctx *ctx, enum dev_scope_type type,
+                              uint enumeration_id, pci_dev_t bdf)
+{
+       /* we don't support longer paths yet */
+       const size_t dev_scope_length = sizeof(struct dev_scope) + 2;
+       struct dev_scope *ds = ctx->current;
+
+       memset(ds, 0, dev_scope_length);
+       ds->type        = type;
+       ds->length      = dev_scope_length;
+       ds->enumeration = enumeration_id;
+       ds->start_bus   = PCI_BUS(bdf);
+       ds->path[0].dev = PCI_DEV(bdf);
+       ds->path[0].fn  = PCI_FUNC(bdf);
+
+       return ds->length;
+}
+
+int acpi_create_dmar_ds_pci_br(struct acpi_ctx *ctx, pci_dev_t bdf)
+{
+       return acpi_create_dmar_ds(ctx, SCOPE_PCI_SUB, 0, bdf);
+}
+
+int acpi_create_dmar_ds_pci(struct acpi_ctx *ctx, pci_dev_t bdf)
+{
+       return acpi_create_dmar_ds(ctx, SCOPE_PCI_ENDPOINT, 0, bdf);
+}
+
+int acpi_create_dmar_ds_ioapic(struct acpi_ctx *ctx, uint enumeration_id,
+                              pci_dev_t bdf)
+{
+       return acpi_create_dmar_ds(ctx, SCOPE_IOAPIC, enumeration_id, bdf);
+}
+
+int acpi_create_dmar_ds_msi_hpet(struct acpi_ctx *ctx, uint enumeration_id,
+                                pci_dev_t bdf)
+{
+       return acpi_create_dmar_ds(ctx, SCOPE_MSI_HPET, enumeration_id, bdf);
+}
+
 /* http://www.intel.com/hardwaredesign/hpetspec_1.pdf */
 int acpi_create_hpet(struct acpi_hpet *hpet)
 {
diff --git a/include/acpi_table.h b/include/acpi_table.h
index 6d91ae85e2..17f2a90af9 100644
--- a/include/acpi_table.h
+++ b/include/acpi_table.h
@@ -418,6 +418,26 @@ enum acpi_upc_type {
        UPC_TYPE_HUB
 };
 
+enum dev_scope_type {
+       SCOPE_PCI_ENDPOINT = 1,
+       SCOPE_PCI_SUB = 2,
+       SCOPE_IOAPIC = 3,
+       SCOPE_MSI_HPET = 4,
+       SCOPE_ACPI_NAMESPACE_DEVICE = 5
+};
+
+struct __packed dev_scope {
+       u8 type;
+       u8 length;
+       u8 reserved[2];
+       u8 enumeration;
+       u8 start_bus;
+       struct {
+               u8 dev;
+               u8 fn;
+       } __packed path[0];
+};
+
 enum dmar_type {
        DMAR_DRHD = 0,
        DMAR_RMRR = 1,
@@ -578,6 +598,13 @@ enum acpi_tables {
  */
 int acpi_get_table_revision(enum acpi_tables table);
 
+int acpi_create_dmar_drhd(struct acpi_ctx *ctx, uint flags, uint segment,
+                         u64 bar);
+int acpi_create_dmar_rmrr(struct acpi_ctx *ctx, uint segment, u64 bar,
+                         u64 limit);
+void acpi_dmar_rmrr_fixup(struct acpi_ctx *ctx, void *base);
+void acpi_dmar_drhd_fixup(struct acpi_ctx *ctx, void *base);
+
 /**
  * acpi_create_dmar() - Create a DMA Remapping Reporting (DMAR) table
  *
@@ -592,6 +619,16 @@ void acpi_create_dbg2(struct acpi_dbg2_header *dbg2,
                      struct acpi_gen_regaddr *address, uint32_t address_size,
                      const char *device_path);
 
+int acpi_create_dmar_ds_pci_br(struct acpi_ctx *ctx, pci_dev_t bdf);
+int acpi_create_dmar_ds_pci(struct acpi_ctx *ctx, pci_dev_t bdf);
+int acpi_create_dmar_ds_ioapic(struct acpi_ctx *ctx, uint enumeration_id,
+                              pci_dev_t bdf);
+int acpi_create_dmar_ds_msi_hpet(struct acpi_ctx *ctx, uint enumeration_id,
+                                pci_dev_t bdf);
+void acpi_fadt_common(struct acpi_fadt *fadt, struct acpi_facs *facs,
+                     void *dsdt);
+void intel_acpi_fill_fadt(struct acpi_fadt *fadt);
+
 /**
  * acpi_fill_header() - Set up a new table header
  *
-- 
2.25.0.341.g760bfbb309-goog

Reply via email to