x86: acpi: Add support for additional Intel tables
Apollo Lake needs to generate a few more table types used on Intel SoCs. Add support for these into the x86 ACPI code. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -98,4 +98,119 @@ int arch_write_sci_irq_select(uint scis);
|
|||||||
*/
|
*/
|
||||||
int arch_madt_sci_irq_polarity(int sci);
|
int arch_madt_sci_irq_polarity(int sci);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_create_dmar_drhd() - Create a table for DMA remapping with the IOMMU
|
||||||
|
*
|
||||||
|
* See here for the specification
|
||||||
|
* https://software.intel.com/sites/default/files/managed/c5/15/vt-directed-io-spec.pdf
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @flags: (DRHD_INCLUDE_...)
|
||||||
|
* @segment: PCI segment asscociated with this unit
|
||||||
|
* @bar: Base address of remapping hardware register-set for this unit
|
||||||
|
*/
|
||||||
|
void acpi_create_dmar_drhd(struct acpi_ctx *ctx, uint flags, uint segment,
|
||||||
|
u64 bar);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_create_dmar_rmrr() - Set up an RMRR
|
||||||
|
*
|
||||||
|
* This sets up a Reserved-Memory Region Reporting structure, used to allow
|
||||||
|
* DMA to regions used by devices that the BIOS controls.
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @segment: PCI segment asscociated with this unit
|
||||||
|
* @bar: Base address of mapping
|
||||||
|
* @limit: End address of mapping
|
||||||
|
*/
|
||||||
|
void acpi_create_dmar_rmrr(struct acpi_ctx *ctx, uint segment, u64 bar,
|
||||||
|
u64 limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_dmar_drhd_fixup() - Set the length of an DRHD
|
||||||
|
*
|
||||||
|
* This sets the DRHD length field based on the current ctx->current
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @base: Address of the start of the DRHD
|
||||||
|
*/
|
||||||
|
void acpi_dmar_drhd_fixup(struct acpi_ctx *ctx, void *base);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_dmar_rmrr_fixup() - Set the length of an RMRR
|
||||||
|
*
|
||||||
|
* This sets the RMRR length field based on the current ctx->current
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @base: Address of the start of the RMRR
|
||||||
|
*/
|
||||||
|
void acpi_dmar_rmrr_fixup(struct acpi_ctx *ctx, void *base);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_create_dmar_ds_pci() - Set up a DMAR scope for a PCI device
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @bdf: PCI device to add
|
||||||
|
* @return length of mapping in bytes
|
||||||
|
*/
|
||||||
|
int acpi_create_dmar_ds_pci(struct acpi_ctx *ctx, pci_dev_t bdf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_create_dmar_ds_pci_br() - Set up a DMAR scope for a PCI bridge
|
||||||
|
*
|
||||||
|
* This is used to provide a mapping for a PCI bridge
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @bdf: PCI device to add
|
||||||
|
* @return length of mapping in bytes
|
||||||
|
*/
|
||||||
|
int acpi_create_dmar_ds_pci_br(struct acpi_ctx *ctx, pci_dev_t bdf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_create_dmar_ds_ioapic() - Set up a DMAR scope for an IOAPIC device
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @enumeration_id: Enumeration ID (typically 2)
|
||||||
|
* @bdf: PCI device to add
|
||||||
|
* @return length of mapping in bytes
|
||||||
|
*/
|
||||||
|
int acpi_create_dmar_ds_ioapic(struct acpi_ctx *ctx, uint enumeration_id,
|
||||||
|
pci_dev_t bdf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_create_dmar_ds_msi_hpet() - Set up a DMAR scope for an HPET
|
||||||
|
*
|
||||||
|
* Sets up a scope for a High-Precision Event Timer that supports
|
||||||
|
* Message-Signalled Interrupts
|
||||||
|
*
|
||||||
|
* @ctx: ACPI context pointer
|
||||||
|
* @enumeration_id: Enumeration ID (typically 0)
|
||||||
|
* @bdf: PCI device to add
|
||||||
|
* @return length of mapping in bytes
|
||||||
|
*/
|
||||||
|
int acpi_create_dmar_ds_msi_hpet(struct acpi_ctx *ctx, uint enumeration_id,
|
||||||
|
pci_dev_t bdf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_fadt_common() - Handle common parts of filling out an FADT
|
||||||
|
*
|
||||||
|
* This sets up the Fixed ACPI Description Table
|
||||||
|
*
|
||||||
|
* @fadt: Pointer to place to put FADT
|
||||||
|
* @facs: Pointer to the FACS
|
||||||
|
* @dsdt: Pointer to the DSDT
|
||||||
|
*/
|
||||||
|
void acpi_fadt_common(struct acpi_fadt *fadt, struct acpi_facs *facs,
|
||||||
|
void *dsdt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_acpi_fill_fadt() - Set up the contents of the FADT
|
||||||
|
*
|
||||||
|
* This sets up parts of the Fixed ACPI Description Table that are common to
|
||||||
|
* Intel chips
|
||||||
|
*
|
||||||
|
* @fadt: Pointer to place to put FADT
|
||||||
|
*/
|
||||||
|
void intel_acpi_fill_fadt(struct acpi_fadt *fadt);
|
||||||
|
|
||||||
#endif /* __ASM_ACPI_TABLE_H__ */
|
#endif /* __ASM_ACPI_TABLE_H__ */
|
||||||
|
|||||||
@@ -629,3 +629,114 @@ int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, OEM_TABLE_ID, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -377,6 +377,49 @@ struct acpi_csrt_shared_info {
|
|||||||
u32 max_block_size;
|
u32 max_block_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Port types for ACPI _UPC object */
|
||||||
|
enum acpi_upc_type {
|
||||||
|
UPC_TYPE_A,
|
||||||
|
UPC_TYPE_MINI_AB,
|
||||||
|
UPC_TYPE_EXPRESSCARD,
|
||||||
|
UPC_TYPE_USB3_A,
|
||||||
|
UPC_TYPE_USB3_B,
|
||||||
|
UPC_TYPE_USB3_MICRO_B,
|
||||||
|
UPC_TYPE_USB3_MICRO_AB,
|
||||||
|
UPC_TYPE_USB3_POWER_B,
|
||||||
|
UPC_TYPE_C_USB2_ONLY,
|
||||||
|
UPC_TYPE_C_USB2_SS_SWITCH,
|
||||||
|
UPC_TYPE_C_USB2_SS,
|
||||||
|
UPC_TYPE_PROPRIETARY = 0xff,
|
||||||
|
/*
|
||||||
|
* The following types are not directly defined in the ACPI
|
||||||
|
* spec but are used by coreboot to identify a USB device type.
|
||||||
|
*/
|
||||||
|
UPC_TYPE_INTERNAL = 0xff,
|
||||||
|
UPC_TYPE_UNUSED,
|
||||||
|
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 {
|
enum dmar_type {
|
||||||
DMAR_DRHD = 0,
|
DMAR_DRHD = 0,
|
||||||
DMAR_RMRR = 1,
|
DMAR_RMRR = 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user