From patchwork Mon Jan 27 05:06:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 240244 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Jan 2020 22:06:39 -0700 Subject: [PATCH 092/108] x86: acpi: Add support for additional DMAR tables In-Reply-To: <20200127050655.170614-1-sjg@chromium.org> References: <20200127050655.170614-1-sjg@chromium.org> Message-ID: <20200126220508.92.I8aa77aa9037dc3d08929270b114eac2f8fc9daa3@changeid> Apollo Lake needs to generate a few more table types. Add support for these into the x86 ACPI code. Signed-off-by: Simon Glass --- 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 *