summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/acpi/Makefile.mk1
-rw-r--r--src/acpi/acpigen_pci_root_resource_producer.c106
-rw-r--r--src/include/acpi/acpigen_pci.h2
-rw-r--r--src/soc/amd/cezanne/chip.c3
-rw-r--r--src/soc/amd/common/block/data_fabric/domain.c99
-rw-r--r--src/soc/amd/common/block/include/amdblocks/data_fabric.h2
-rw-r--r--src/soc/amd/genoa_poc/domain.c3
-rw-r--r--src/soc/amd/glinda/chip.c3
-rw-r--r--src/soc/amd/mendocino/chip.c3
-rw-r--r--src/soc/amd/phoenix/chip.c3
-rw-r--r--src/soc/amd/picasso/chip.c3
11 files changed, 121 insertions, 107 deletions
diff --git a/src/acpi/Makefile.mk b/src/acpi/Makefile.mk
index 6bb34cb29d..e9d5cb0fda 100644
--- a/src/acpi/Makefile.mk
+++ b/src/acpi/Makefile.mk
@@ -7,6 +7,7 @@ ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32)$(CONFIG_ARCH_RAMSTAGE_X86_64),y)
ramstage-y += acpi_apic.c
ramstage-y += acpi_dmar.c
ramstage-y += acpi_hpet.c
+ramstage-y += acpigen_pci_root_resource_producer.c
endif
ramstage-$(CONFIG_ACPI_PPTT) += acpi_pptt.c
ramstage-y += acpigen.c
diff --git a/src/acpi/acpigen_pci_root_resource_producer.c b/src/acpi/acpigen_pci_root_resource_producer.c
new file mode 100644
index 0000000000..c9efe0e34a
--- /dev/null
+++ b/src/acpi/acpigen_pci_root_resource_producer.c
@@ -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();
+}
diff --git a/src/include/acpi/acpigen_pci.h b/src/include/acpi/acpigen_pci.h
index 8a96eb3d25..69216ec4fa 100644
--- a/src/include/acpi/acpigen_pci.h
+++ b/src/include/acpi/acpigen_pci.h
@@ -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,
const char *source_path, unsigned int index);
+void pci_domain_fill_ssdt(const struct device *domain);
+
#endif /* ACPIGEN_PCI_H */
diff --git a/src/soc/amd/cezanne/chip.c b/src/soc/amd/cezanne/chip.c
index 83fd5c6a16..7463352963 100644
--- a/src/soc/amd/cezanne/chip.c
+++ b/src/soc/amd/cezanne/chip.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <acpi/acpigen_pci.h>
#include <amdblocks/acpi.h>
#include <amdblocks/data_fabric.h>
#include <amdblocks/fsp.h>
@@ -32,7 +33,7 @@ struct device_operations cezanne_pci_domain_ops = {
.scan_bus = amd_pci_domain_scan_bus,
.init = amd_pci_domain_init,
.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)
diff --git a/src/soc/amd/common/block/data_fabric/domain.c b/src/soc/amd/common/block/data_fabric/domain.c
index ab85e2b592..b056d607c7 100644
--- a/src/soc/amd/common/block/data_fabric/domain.c
+++ b/src/soc/amd/common/block/data_fabric/domain.c
@@ -1,10 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#include <acpi/acpigen.h>
#include <amdblocks/data_fabric.h>
#include <amdblocks/root_complex.h>
#include <arch/ioapic.h>
-#include <arch/vga.h>
#include <console/console.h>
#include <cpu/amd/mtrr.h>
#include <cpu/cpu.h>
@@ -214,100 +212,3 @@ void amd_pci_domain_read_resources(struct device *domain)
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();
-}
diff --git a/src/soc/amd/common/block/include/amdblocks/data_fabric.h b/src/soc/amd/common/block/include/amdblocks/data_fabric.h
index f0073dfb4e..fbed0b22a0 100644
--- a/src/soc/amd/common/block/include/amdblocks/data_fabric.h
+++ b/src/soc/amd/common/block/include/amdblocks/data_fabric.h
@@ -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_scan_bus(struct device *domain);
-void amd_pci_domain_fill_ssdt(const struct device *domain);
-
#endif /* AMD_BLOCK_DATA_FABRIC_H */
diff --git a/src/soc/amd/genoa_poc/domain.c b/src/soc/amd/genoa_poc/domain.c
index 14248cdda5..5672f65ce6 100644
--- a/src/soc/amd/genoa_poc/domain.c
+++ b/src/soc/amd/genoa_poc/domain.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <acpi/acpigen_pci.h>
#include <amdblocks/ioapic.h>
#include <amdblocks/data_fabric.h>
#include <amdblocks/root_complex.h>
@@ -63,5 +64,5 @@ struct device_operations genoa_pci_domain_ops = {
.scan_bus = amd_pci_domain_scan_bus,
.init = amd_pci_domain_init,
.acpi_name = genoa_domain_acpi_name,
- .acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
+ .acpi_fill_ssdt = pci_domain_fill_ssdt,
};
diff --git a/src/soc/amd/glinda/chip.c b/src/soc/amd/glinda/chip.c
index 515580d8fb..e227f41599 100644
--- a/src/soc/amd/glinda/chip.c
+++ b/src/soc/amd/glinda/chip.c
@@ -2,6 +2,7 @@
/* TODO: Update for Glinda */
+#include <acpi/acpigen_pci.h>
#include <amdblocks/acpi.h>
#include <amdblocks/data_fabric.h>
#include <amdblocks/fsp.h>
@@ -34,7 +35,7 @@ struct device_operations glinda_pci_domain_ops = {
.scan_bus = amd_pci_domain_scan_bus,
.init = amd_pci_domain_init,
.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)
diff --git a/src/soc/amd/mendocino/chip.c b/src/soc/amd/mendocino/chip.c
index 729f97ad0e..fb61f5852a 100644
--- a/src/soc/amd/mendocino/chip.c
+++ b/src/soc/amd/mendocino/chip.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <acpi/acpigen_pci.h>
#include <amdblocks/acpi.h>
#include <amdblocks/data_fabric.h>
#include <amdblocks/fsp.h>
@@ -32,7 +33,7 @@ struct device_operations mendocino_pci_domain_ops = {
.scan_bus = amd_pci_domain_scan_bus,
.init = amd_pci_domain_init,
.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)
diff --git a/src/soc/amd/phoenix/chip.c b/src/soc/amd/phoenix/chip.c
index f45e7b8a6b..a88468b28d 100644
--- a/src/soc/amd/phoenix/chip.c
+++ b/src/soc/amd/phoenix/chip.c
@@ -2,6 +2,7 @@
/* TODO: Update for Phoenix */
+#include <acpi/acpigen_pci.h>
#include <amdblocks/acpi.h>
#include <amdblocks/data_fabric.h>
#include <amdblocks/fsp.h>
@@ -35,7 +36,7 @@ struct device_operations phoenix_pci_domain_ops = {
.scan_bus = amd_pci_domain_scan_bus,
.init = amd_pci_domain_init,
.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)
diff --git a/src/soc/amd/picasso/chip.c b/src/soc/amd/picasso/chip.c
index 7411948fe8..e642060ff0 100644
--- a/src/soc/amd/picasso/chip.c
+++ b/src/soc/amd/picasso/chip.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <acpi/acpigen_pci.h>
#include <amdblocks/acpi.h>
#include <amdblocks/data_fabric.h>
#include <amdblocks/fsp.h>
@@ -33,7 +34,7 @@ struct device_operations picasso_pci_domain_ops = {
.scan_bus = amd_pci_domain_scan_bus,
.init = amd_pci_domain_init,
.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)