soc/amd: move common pci_domain_fill_ssdt implementation to acpi/
Even though it has an 'amd_' prefix, the amd_pci_domain_fill_ssdt implementation doesn't contain any AMD-specific code and can also be used by other SoCs. So factor it out, move the implementation to src/acpi/acpigen_pci_root_resource_producer.c, and rename it to pci_domain_fill_ssdt. When a SoC now assigns pci_domain_fill_ssdt to its domain operation's acpi_fill_ssdt function pointer, the PCI domain resource producer information will be added to the SSDT. Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: I7bd8568cf0b7051c74adbedfe0e416a0938ccb99 Reviewed-on: https://review.coreboot.org/c/coreboot/+/80464 Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
d361163f6b
commit
e549ee093b
@ -7,6 +7,7 @@ ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32)$(CONFIG_ARCH_RAMSTAGE_X86_64),y)
|
|||||||
ramstage-y += acpi_apic.c
|
ramstage-y += acpi_apic.c
|
||||||
ramstage-y += acpi_dmar.c
|
ramstage-y += acpi_dmar.c
|
||||||
ramstage-y += acpi_hpet.c
|
ramstage-y += acpi_hpet.c
|
||||||
|
ramstage-y += acpigen_pci_root_resource_producer.c
|
||||||
endif
|
endif
|
||||||
ramstage-$(CONFIG_ACPI_PPTT) += acpi_pptt.c
|
ramstage-$(CONFIG_ACPI_PPTT) += acpi_pptt.c
|
||||||
ramstage-y += acpigen.c
|
ramstage-y += acpigen.c
|
||||||
|
106
src/acpi/acpigen_pci_root_resource_producer.c
Normal file
106
src/acpi/acpigen_pci_root_resource_producer.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <acpi/acpigen.h>
|
||||||
|
#include <acpi/acpigen_pci.h>
|
||||||
|
#include <arch/pci_io_cfg.h>
|
||||||
|
#include <arch/vga.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <device/device.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
static void write_ssdt_domain_io_producer_range_helper(const char *domain_name,
|
||||||
|
resource_t base, resource_t limit)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "%s _CRS: adding IO range [%llx-%llx]\n", domain_name, base, limit);
|
||||||
|
acpigen_resource_producer_io(base, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_ssdt_domain_io_producer_range(const char *domain_name,
|
||||||
|
resource_t base, resource_t limit)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Split the IO region at the PCI config IO ports so that the IO resource producer
|
||||||
|
* won't cover the same IO ports that the IO resource consumer for the PCI config IO
|
||||||
|
* ports in the same ACPI device already covers.
|
||||||
|
*/
|
||||||
|
if (base < PCI_IO_CONFIG_INDEX) {
|
||||||
|
write_ssdt_domain_io_producer_range_helper(domain_name,
|
||||||
|
base,
|
||||||
|
MIN(limit, PCI_IO_CONFIG_INDEX - 1));
|
||||||
|
}
|
||||||
|
if (limit > PCI_IO_CONFIG_LAST_PORT) {
|
||||||
|
write_ssdt_domain_io_producer_range_helper(domain_name,
|
||||||
|
MAX(base, PCI_IO_CONFIG_LAST_PORT + 1),
|
||||||
|
limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_ssdt_domain_mmio_producer_range(const char *domain_name,
|
||||||
|
resource_t base, resource_t limit)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "%s _CRS: adding MMIO range [%llx-%llx]\n",
|
||||||
|
domain_name, base, limit);
|
||||||
|
acpigen_resource_producer_mmio(base, limit,
|
||||||
|
MEM_RSRC_FLAG_MEM_READ_WRITE | MEM_RSRC_FLAG_MEM_ATTR_NON_CACHE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pci_domain_fill_ssdt(const struct device *domain)
|
||||||
|
{
|
||||||
|
const char *acpi_scope = acpi_device_path(domain);
|
||||||
|
printk(BIOS_DEBUG, "%s ACPI scope: '%s'\n", __func__, acpi_scope);
|
||||||
|
acpigen_write_scope(acpi_device_path(domain));
|
||||||
|
|
||||||
|
acpigen_write_name("_CRS");
|
||||||
|
acpigen_write_resourcetemplate_header();
|
||||||
|
|
||||||
|
/* PCI bus number range in domain */
|
||||||
|
printk(BIOS_DEBUG, "%s _CRS: adding busses [%x-%x] in segment group %x\n",
|
||||||
|
acpi_device_name(domain), domain->downstream->secondary,
|
||||||
|
domain->downstream->max_subordinate, domain->downstream->segment_group);
|
||||||
|
acpigen_resource_producer_bus_number(domain->downstream->secondary,
|
||||||
|
domain->downstream->max_subordinate);
|
||||||
|
|
||||||
|
if (domain->path.domain.domain == 0) {
|
||||||
|
/* ACPI 6.4.2.5 I/O Port Descriptor */
|
||||||
|
acpigen_write_io16(PCI_IO_CONFIG_INDEX, PCI_IO_CONFIG_LAST_PORT, 1,
|
||||||
|
PCI_IO_CONFIG_PORT_COUNT, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct resource *res;
|
||||||
|
for (res = domain->resource_list; res != NULL; res = res->next) {
|
||||||
|
if (!(res->flags & IORESOURCE_ASSIGNED))
|
||||||
|
continue;
|
||||||
|
/* Don't add MMIO producer ranges for reserved MMIO regions from non-PCI
|
||||||
|
devices */
|
||||||
|
if (res->flags & IORESOURCE_RESERVE)
|
||||||
|
continue;
|
||||||
|
/* Don't add MMIO producer ranges for DRAM regions */
|
||||||
|
if (res->flags & IORESOURCE_STORED)
|
||||||
|
continue;
|
||||||
|
switch (res->flags & IORESOURCE_TYPE_MASK) {
|
||||||
|
case IORESOURCE_IO:
|
||||||
|
write_ssdt_domain_io_producer_range(acpi_device_name(domain),
|
||||||
|
res->base, res->limit);
|
||||||
|
break;
|
||||||
|
case IORESOURCE_MEM:
|
||||||
|
write_ssdt_domain_mmio_producer_range(acpi_device_name(domain),
|
||||||
|
res->base, res->limit);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain->downstream->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
|
||||||
|
printk(BIOS_DEBUG, "%s _CRS: adding VGA resource\n", acpi_device_name(domain));
|
||||||
|
acpigen_resource_producer_mmio(VGA_MMIO_BASE, VGA_MMIO_LIMIT,
|
||||||
|
MEM_RSRC_FLAG_MEM_READ_WRITE | MEM_RSRC_FLAG_MEM_ATTR_CACHE);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpigen_write_resourcetemplate_footer();
|
||||||
|
|
||||||
|
acpigen_write_SEG(domain->downstream->segment_group);
|
||||||
|
acpigen_write_BBN(domain->downstream->secondary);
|
||||||
|
/* Scope */
|
||||||
|
acpigen_pop_len();
|
||||||
|
}
|
@ -14,4 +14,6 @@ void acpigen_write_PRT_GSI_entry(unsigned int pci_dev, unsigned int acpi_pin, un
|
|||||||
void acpigen_write_PRT_source_entry(unsigned int pci_dev, unsigned int acpi_pin,
|
void acpigen_write_PRT_source_entry(unsigned int pci_dev, unsigned int acpi_pin,
|
||||||
const char *source_path, unsigned int index);
|
const char *source_path, unsigned int index);
|
||||||
|
|
||||||
|
void pci_domain_fill_ssdt(const struct device *domain);
|
||||||
|
|
||||||
#endif /* ACPIGEN_PCI_H */
|
#endif /* ACPIGEN_PCI_H */
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <acpi/acpigen_pci.h>
|
||||||
#include <amdblocks/acpi.h>
|
#include <amdblocks/acpi.h>
|
||||||
#include <amdblocks/data_fabric.h>
|
#include <amdblocks/data_fabric.h>
|
||||||
#include <amdblocks/fsp.h>
|
#include <amdblocks/fsp.h>
|
||||||
@ -32,7 +33,7 @@ struct device_operations cezanne_pci_domain_ops = {
|
|||||||
.scan_bus = amd_pci_domain_scan_bus,
|
.scan_bus = amd_pci_domain_scan_bus,
|
||||||
.init = amd_pci_domain_init,
|
.init = amd_pci_domain_init,
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
.acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
|
.acpi_fill_ssdt = pci_domain_fill_ssdt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void soc_init(void *chip_info)
|
static void soc_init(void *chip_info)
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
#include <acpi/acpigen.h>
|
|
||||||
#include <amdblocks/data_fabric.h>
|
#include <amdblocks/data_fabric.h>
|
||||||
#include <amdblocks/root_complex.h>
|
#include <amdblocks/root_complex.h>
|
||||||
#include <arch/ioapic.h>
|
#include <arch/ioapic.h>
|
||||||
#include <arch/vga.h>
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/amd/mtrr.h>
|
#include <cpu/amd/mtrr.h>
|
||||||
#include <cpu/cpu.h>
|
#include <cpu/cpu.h>
|
||||||
@ -214,100 +212,3 @@ void amd_pci_domain_read_resources(struct device *domain)
|
|||||||
read_soc_memmap_resources(domain, &idx);
|
read_soc_memmap_resources(domain, &idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_ssdt_domain_io_producer_range_helper(const char *domain_name,
|
|
||||||
resource_t base, resource_t limit)
|
|
||||||
{
|
|
||||||
printk(BIOS_DEBUG, "%s _CRS: adding IO range [%llx-%llx]\n", domain_name, base, limit);
|
|
||||||
acpigen_resource_producer_io(base, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_ssdt_domain_io_producer_range(const char *domain_name,
|
|
||||||
resource_t base, resource_t limit)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Split the IO region at the PCI config IO ports so that the IO resource producer
|
|
||||||
* won't cover the same IO ports that the IO resource consumer for the PCI config IO
|
|
||||||
* ports in the same ACPI device already covers.
|
|
||||||
*/
|
|
||||||
if (base < PCI_IO_CONFIG_INDEX) {
|
|
||||||
write_ssdt_domain_io_producer_range_helper(domain_name,
|
|
||||||
base,
|
|
||||||
MIN(limit, PCI_IO_CONFIG_INDEX - 1));
|
|
||||||
}
|
|
||||||
if (limit > PCI_IO_CONFIG_LAST_PORT) {
|
|
||||||
write_ssdt_domain_io_producer_range_helper(domain_name,
|
|
||||||
MAX(base, PCI_IO_CONFIG_LAST_PORT + 1),
|
|
||||||
limit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_ssdt_domain_mmio_producer_range(const char *domain_name,
|
|
||||||
resource_t base, resource_t limit)
|
|
||||||
{
|
|
||||||
printk(BIOS_DEBUG, "%s _CRS: adding MMIO range [%llx-%llx]\n",
|
|
||||||
domain_name, base, limit);
|
|
||||||
acpigen_resource_producer_mmio(base, limit,
|
|
||||||
MEM_RSRC_FLAG_MEM_READ_WRITE | MEM_RSRC_FLAG_MEM_ATTR_NON_CACHE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void amd_pci_domain_fill_ssdt(const struct device *domain)
|
|
||||||
{
|
|
||||||
const char *acpi_scope = acpi_device_path(domain);
|
|
||||||
printk(BIOS_DEBUG, "%s ACPI scope: '%s'\n", __func__, acpi_scope);
|
|
||||||
acpigen_write_scope(acpi_device_path(domain));
|
|
||||||
|
|
||||||
acpigen_write_name("_CRS");
|
|
||||||
acpigen_write_resourcetemplate_header();
|
|
||||||
|
|
||||||
/* PCI bus number range in domain */
|
|
||||||
printk(BIOS_DEBUG, "%s _CRS: adding busses [%x-%x] in segment group %x\n",
|
|
||||||
acpi_device_name(domain), domain->downstream->secondary,
|
|
||||||
domain->downstream->max_subordinate, domain->downstream->segment_group);
|
|
||||||
acpigen_resource_producer_bus_number(domain->downstream->secondary,
|
|
||||||
domain->downstream->max_subordinate);
|
|
||||||
|
|
||||||
if (domain->path.domain.domain == 0) {
|
|
||||||
/* ACPI 6.4.2.5 I/O Port Descriptor */
|
|
||||||
acpigen_write_io16(PCI_IO_CONFIG_INDEX, PCI_IO_CONFIG_LAST_PORT, 1,
|
|
||||||
PCI_IO_CONFIG_PORT_COUNT, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct resource *res;
|
|
||||||
for (res = domain->resource_list; res != NULL; res = res->next) {
|
|
||||||
if (!(res->flags & IORESOURCE_ASSIGNED))
|
|
||||||
continue;
|
|
||||||
/* Don't add MMIO producer ranges for reserved MMIO regions from non-PCI
|
|
||||||
devices */
|
|
||||||
if (res->flags & IORESOURCE_RESERVE)
|
|
||||||
continue;
|
|
||||||
/* Don't add MMIO producer ranges for DRAM regions */
|
|
||||||
if (res->flags & IORESOURCE_STORED)
|
|
||||||
continue;
|
|
||||||
switch (res->flags & IORESOURCE_TYPE_MASK) {
|
|
||||||
case IORESOURCE_IO:
|
|
||||||
write_ssdt_domain_io_producer_range(acpi_device_name(domain),
|
|
||||||
res->base, res->limit);
|
|
||||||
break;
|
|
||||||
case IORESOURCE_MEM:
|
|
||||||
write_ssdt_domain_mmio_producer_range(acpi_device_name(domain),
|
|
||||||
res->base, res->limit);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domain->downstream->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
|
|
||||||
printk(BIOS_DEBUG, "%s _CRS: adding VGA resource\n", acpi_device_name(domain));
|
|
||||||
acpigen_resource_producer_mmio(VGA_MMIO_BASE, VGA_MMIO_LIMIT,
|
|
||||||
MEM_RSRC_FLAG_MEM_READ_WRITE | MEM_RSRC_FLAG_MEM_ATTR_CACHE);
|
|
||||||
}
|
|
||||||
|
|
||||||
acpigen_write_resourcetemplate_footer();
|
|
||||||
|
|
||||||
acpigen_write_SEG(domain->downstream->segment_group);
|
|
||||||
acpigen_write_BBN(domain->downstream->secondary);
|
|
||||||
/* Scope */
|
|
||||||
acpigen_pop_len();
|
|
||||||
}
|
|
||||||
|
@ -55,6 +55,4 @@ void data_fabric_get_mmio_base_size(unsigned int reg, resource_t *mmio_base,
|
|||||||
void amd_pci_domain_read_resources(struct device *domain);
|
void amd_pci_domain_read_resources(struct device *domain);
|
||||||
void amd_pci_domain_scan_bus(struct device *domain);
|
void amd_pci_domain_scan_bus(struct device *domain);
|
||||||
|
|
||||||
void amd_pci_domain_fill_ssdt(const struct device *domain);
|
|
||||||
|
|
||||||
#endif /* AMD_BLOCK_DATA_FABRIC_H */
|
#endif /* AMD_BLOCK_DATA_FABRIC_H */
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <acpi/acpigen_pci.h>
|
||||||
#include <amdblocks/ioapic.h>
|
#include <amdblocks/ioapic.h>
|
||||||
#include <amdblocks/data_fabric.h>
|
#include <amdblocks/data_fabric.h>
|
||||||
#include <amdblocks/root_complex.h>
|
#include <amdblocks/root_complex.h>
|
||||||
@ -63,5 +64,5 @@ struct device_operations genoa_pci_domain_ops = {
|
|||||||
.scan_bus = amd_pci_domain_scan_bus,
|
.scan_bus = amd_pci_domain_scan_bus,
|
||||||
.init = amd_pci_domain_init,
|
.init = amd_pci_domain_init,
|
||||||
.acpi_name = genoa_domain_acpi_name,
|
.acpi_name = genoa_domain_acpi_name,
|
||||||
.acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
|
.acpi_fill_ssdt = pci_domain_fill_ssdt,
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
/* TODO: Update for Glinda */
|
/* TODO: Update for Glinda */
|
||||||
|
|
||||||
|
#include <acpi/acpigen_pci.h>
|
||||||
#include <amdblocks/acpi.h>
|
#include <amdblocks/acpi.h>
|
||||||
#include <amdblocks/data_fabric.h>
|
#include <amdblocks/data_fabric.h>
|
||||||
#include <amdblocks/fsp.h>
|
#include <amdblocks/fsp.h>
|
||||||
@ -34,7 +35,7 @@ struct device_operations glinda_pci_domain_ops = {
|
|||||||
.scan_bus = amd_pci_domain_scan_bus,
|
.scan_bus = amd_pci_domain_scan_bus,
|
||||||
.init = amd_pci_domain_init,
|
.init = amd_pci_domain_init,
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
.acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
|
.acpi_fill_ssdt = pci_domain_fill_ssdt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void soc_init(void *chip_info)
|
static void soc_init(void *chip_info)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <acpi/acpigen_pci.h>
|
||||||
#include <amdblocks/acpi.h>
|
#include <amdblocks/acpi.h>
|
||||||
#include <amdblocks/data_fabric.h>
|
#include <amdblocks/data_fabric.h>
|
||||||
#include <amdblocks/fsp.h>
|
#include <amdblocks/fsp.h>
|
||||||
@ -32,7 +33,7 @@ struct device_operations mendocino_pci_domain_ops = {
|
|||||||
.scan_bus = amd_pci_domain_scan_bus,
|
.scan_bus = amd_pci_domain_scan_bus,
|
||||||
.init = amd_pci_domain_init,
|
.init = amd_pci_domain_init,
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
.acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
|
.acpi_fill_ssdt = pci_domain_fill_ssdt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void soc_init(void *chip_info)
|
static void soc_init(void *chip_info)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
/* TODO: Update for Phoenix */
|
/* TODO: Update for Phoenix */
|
||||||
|
|
||||||
|
#include <acpi/acpigen_pci.h>
|
||||||
#include <amdblocks/acpi.h>
|
#include <amdblocks/acpi.h>
|
||||||
#include <amdblocks/data_fabric.h>
|
#include <amdblocks/data_fabric.h>
|
||||||
#include <amdblocks/fsp.h>
|
#include <amdblocks/fsp.h>
|
||||||
@ -35,7 +36,7 @@ struct device_operations phoenix_pci_domain_ops = {
|
|||||||
.scan_bus = amd_pci_domain_scan_bus,
|
.scan_bus = amd_pci_domain_scan_bus,
|
||||||
.init = amd_pci_domain_init,
|
.init = amd_pci_domain_init,
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
.acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
|
.acpi_fill_ssdt = pci_domain_fill_ssdt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void soc_init(void *chip_info)
|
static void soc_init(void *chip_info)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <acpi/acpigen_pci.h>
|
||||||
#include <amdblocks/acpi.h>
|
#include <amdblocks/acpi.h>
|
||||||
#include <amdblocks/data_fabric.h>
|
#include <amdblocks/data_fabric.h>
|
||||||
#include <amdblocks/fsp.h>
|
#include <amdblocks/fsp.h>
|
||||||
@ -33,7 +34,7 @@ struct device_operations picasso_pci_domain_ops = {
|
|||||||
.scan_bus = amd_pci_domain_scan_bus,
|
.scan_bus = amd_pci_domain_scan_bus,
|
||||||
.init = amd_pci_domain_init,
|
.init = amd_pci_domain_init,
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
.acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
|
.acpi_fill_ssdt = pci_domain_fill_ssdt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void soc_init(void *chip_info)
|
static void soc_init(void *chip_info)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user