From 30d9513250997abeafa15ce945343b21dd303f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 10:46:21 +0100 Subject: [PATCH 01/11] northbridge/amd/pi/00730F01/acpi/northbridge.asl: Add IOMMU device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- .../amd/pi/00730F01/acpi/northbridge.asl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl b/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl index d502af4137d..df6aea063be 100644 --- a/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl +++ b/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl @@ -31,6 +31,19 @@ Device(AMRT) { Name(_ADR, 0x00000000) } /* end AMRT */ +Device(IOMU) { + Name(_ADR, 0x00000002) + + Method(_PRT,0, NotSerialized) + { + If(PICM) + { + Return(APR0) /* APIC mode */ + } + Return (PR0) /* PIC Mode */ + } +} /* end AMRT */ + /* Gpp 0 */ Device(PBR4) { Name(_ADR, 0x00020001) From e6353d99791c94ba0fe5a95ce47403a38dd842de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 10:47:17 +0100 Subject: [PATCH 02/11] src/mainboard/pcengines/apu2/acpi/routing.asl: Add PCI INT routing for IOMMU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- src/mainboard/pcengines/apu2/acpi/routing.asl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mainboard/pcengines/apu2/acpi/routing.asl b/src/mainboard/pcengines/apu2/acpi/routing.asl index 106259d0a99..81211123a7a 100644 --- a/src/mainboard/pcengines/apu2/acpi/routing.asl +++ b/src/mainboard/pcengines/apu2/acpi/routing.asl @@ -3,7 +3,8 @@ /* Routing is in System Bus scope */ Name(PR0, Package(){ /* NB devices */ - /* Bus 0, Dev 0 - F16 Host Controller */ + /* Bus 0, Dev 0 - F0:F16 Host Controller/F2:IOMMU */ + Package(){0x0000FFFF, 0, INTA, 0 }, /* Bus 0, Dev 1 - PCI Bridge for Internal Graphics(IGP) */ /* Bus 0, Dev 1, Func 1 - HDMI Audio Controller */ @@ -46,7 +47,8 @@ Name(PR0, Package(){ Name(APR0, Package(){ /* NB devices in APIC mode */ - /* Bus 0, Dev 0 - F15 Host Controller */ + /* Bus 0, Dev 0 - F0:F16 Host Controller/F2:IOMMU */ + Package(){0x0000FFFF, 0, 0, 16 }, /* Bus 0, Dev 1 - PCI Bridge for Internal Graphics(IGP) */ Package(){0x0001FFFF, 0, 0, 44 }, From 65c40ff44940f3fd6f515e577af28cc9ba878fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 10:49:50 +0100 Subject: [PATCH 03/11] northbridge/amd/pi/00730F01/northbridge.c: Disable Guest AVIC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- src/northbridge/amd/pi/00730F01/northbridge.c | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 046797f5bb7..aa1cc94dc9f 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -85,9 +85,59 @@ static void nb_read_resources(struct device *dev) add_fixed_resources(dev, 0); } +#define IOMMU_MMIO_CONTROL_REG 0x80 +#define IOMMU_MMIO_CONTROL_GAM_SUP_MASK (7 << 21) +#define IOMMU_CONTROL_REG 0x18 +#define IOMMU_CONTROL_GA_EN_MASK (7 << 25) +#define IOMMU_CONTROL_GA_LOG_EN (1 << 28) +#define IOMMU_CONTROL_GA_INT_EN (1 << 29) +#define IOMMU_CONTROL_GA_MASK ( \ + IOMMU_CONTROL_GA_EN_MASK | \ + IOMMU_CONTROL_GA_LOG_EN | \ + IOMMU_CONTROL_GA_INT_EN \ + ) +#define IOMMU_MMIO32(x) (*((volatile uint32_t *)(x))) +#define EFR_SUPPORT BIT(27) + +static void iommu_disable_guest_avic(void) +{ + struct device *iommu; + struct resource *res; + uint32_t iommu_control; + + iommu = pcidev_on_root(0, 2); + + if (!iommu || !iommu->enabled) + return; + + printk(BIOS_DEBUG, "IOMMU: hiding Guest AVIC capability\n"); + pci_and_config32(iommu, IOMMU_MMIO_CONTROL_REG, ~IOMMU_MMIO_CONTROL_GAM_SUP_MASK); + + res = find_resource(iommu, 0x44); + if (!res) + return; + + iommu_control = IOMMU_MMIO32((uintptr_t)res->base + IOMMU_CONTROL_REG); + if (!(iommu_control & IOMMU_CONTROL_GA_MASK)) + return; + + printk(BIOS_DEBUG, "IOMMU: disabling Guest AVIC feature\n"); + iommu_control &= ~IOMMU_CONTROL_GA_MASK; + IOMMU_MMIO32((uintptr_t)res->base + IOMMU_CONTROL_REG) = iommu_control; +} + static void northbridge_init(struct device *dev) { register_new_ioapic((u8 *)IO_APIC2_ADDR); + + /* + * Guest AVIC seems not to be supported on this HW, but the IOMMU + * guest AVIC capability is exposed by default. + * Also the CPUID reports AVIC as not supported by default. + * Disable IOMMU gueast AVIC support so Linux won't complain. + */ + if (!(cpuid_edx(0x8000000A) & BIT(13))) + iommu_disable_guest_avic(); } static unsigned long acpi_fill_hest(acpi_hest_t *hest) @@ -261,9 +311,6 @@ static void add_ivhd_device_entries(struct device *parent, struct device *dev, free(root_level); } -#define IOMMU_MMIO32(x) (*((volatile uint32_t *)(x))) -#define EFR_SUPPORT BIT(27) - static unsigned long acpi_fill_ivrs11(unsigned long current, acpi_ivrs_t *ivrs_agesa) { acpi_ivrs_ivhd11_t *ivhd_11; From d3c3fff0fc373be0eca417c8124e01265489c2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 10:51:02 +0100 Subject: [PATCH 04/11] nb/amd/pi/00730F01/northbridge.c: Enable GNB IOAPIC in northbridge_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the GNB IOAPIC enabling to northbridge init where the IOAPIC is initialized. Remove the comment about IoapicSbFeatureEn, this bit is not touched here. Signed-off-by: Michał Żygowski --- src/northbridge/amd/pi/00730F01/northbridge.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index aa1cc94dc9f..007518e11aa 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -128,8 +128,18 @@ static void iommu_disable_guest_avic(void) static void northbridge_init(struct device *dev) { + struct device *nb = pcidev_on_root(0, 0); + + /* Enable GNB IOAPIC extended IDs */ + pci_write_config32(nb, 0xF8, 0); + pci_or_config32(nb, 0xFC, 1 << 2); + register_new_ioapic((u8 *)IO_APIC2_ADDR); + /* Enable GNB IOAPIC */ + pci_write_config32(nb, 0xF8, 0); + pci_or_config32(nb, 0xFC, 1); + /* * Guest AVIC seems not to be supported on this HW, but the IOMMU * guest AVIC capability is exposed by default. @@ -563,10 +573,7 @@ struct device_operations amd_pi_northbridge_ops = { static void fam16_finalize(void *chip_info) { struct device *dev; - dev = pcidev_on_root(0, 0); /* clear IoapicSbFeatureEn */ - - pci_write_config32(dev, 0xF8, 0); - pci_write_config32(dev, 0xFC, 5); /* TODO: move it to dsdt.asl */ + dev = pcidev_on_root(0, 0); /* * Currently it is impossible to enable ACS with AGESA by setting the From 716d21712fb054690f9c2c4ff412834b9a330f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 10:52:48 +0100 Subject: [PATCH 05/11] src/mainboard/pcengines/apu2/mainboard.c: Assign INTB# to IRQ17 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- src/mainboard/pcengines/apu2/mainboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/pcengines/apu2/mainboard.c b/src/mainboard/pcengines/apu2/mainboard.c index 11f6526c204..3766867eec3 100644 --- a/src/mainboard/pcengines/apu2/mainboard.c +++ b/src/mainboard/pcengines/apu2/mainboard.c @@ -64,7 +64,7 @@ static const u8 mainboard_picr_data[FCH_INT_TABLE_SIZE] = { static const u8 mainboard_intr_data[FCH_INT_TABLE_SIZE] = { [0 ... FCH_INT_TABLE_SIZE-1] = 0x1F, /* INTA# - INTH# */ - [0x00] = 0x10,0x10,0x12,0x13,0x14,0x15,0x1F,0x1F, + [0x00] = 0x10,0x11,0x12,0x13,0x14,0x15,0x1F,0x1F, /* Misc-nil,0,1,2, INT from Serial irq */ [0x08] = 0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F, /* SCI, SMBUS0, ASF, HDA, FC, RSVD, PerMon, SD */ From 6986e35a39b9b7507ea268b2d9520679ec3f51d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 10:53:13 +0100 Subject: [PATCH 06/11] src/mainboard/pcengines/apu2/mainboard.c: Clear the right bits in ECC register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- src/mainboard/pcengines/apu2/mainboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/pcengines/apu2/mainboard.c b/src/mainboard/pcengines/apu2/mainboard.c index 3766867eec3..a0e11f11a9a 100644 --- a/src/mainboard/pcengines/apu2/mainboard.c +++ b/src/mainboard/pcengines/apu2/mainboard.c @@ -425,7 +425,7 @@ static void mainboard_final(void *chip_info) * doesn't work when these bits are set. */ val = pci_read_config32(D18F3, 0xB8); - val &= 0xF000003F; + val &= 0xF00003FF; pci_write_config32(D18F3, 0xB8, val); /* Disable ECC exclusion range */ From fe8a30185c629f088c41d61b6e487d0e028ea094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 11:06:27 +0100 Subject: [PATCH 07/11] src/northbridge/amd/pi/00730F01/northbridge.c: Add PCI_DEVID macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce PCI_DEVID macro which allows to construct PCI device addresses or range with bus numbers. Signed-off-by: Michał Żygowski --- src/include/acpi/acpi_ivrs.h | 5 +++++ src/northbridge/amd/pi/00730F01/northbridge.c | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/include/acpi/acpi_ivrs.h b/src/include/acpi/acpi_ivrs.h index ad86e6a2f39..8ac9b9eba6b 100644 --- a/src/include/acpi/acpi_ivrs.h +++ b/src/include/acpi/acpi_ivrs.h @@ -169,6 +169,11 @@ #define CAP_OFFSET_10_MSI_NUM_PPR_SHIFT 27 #define CAP_OFFSET_10_MSI_NUM_PPR (0x1f << CAP_OFFSET_10_MSI_NUM_PPR_SHIFT) +#define PCI_DEVID(BUS, DEV, FN) ( \ + (((BUS) & 0xFF) << 8) | \ + (((DEV) & 0x1F) << 3) | \ + (((FN) & 0x07))) + /* IVHD (I/O Virtualization Hardware Definition Block) 4-byte entry */ typedef struct ivrs_ivhd_generic { uint8_t type; diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 007518e11aa..7c874187de0 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -180,7 +180,7 @@ static unsigned long acpi_fill_ivrs_ioapic(acpi_ivrs_t *ivrs, unsigned long curr IVHD_DTE_SYS_MGT_NO_TRANS | IVHD_DTE_NMI_PASS | IVHD_DTE_EXT_INT_PASS | IVHD_DTE_INIT_PASS; ivhd_ioapic->handle = get_ioapic_id(VIO_APIC_VADDR); - ivhd_ioapic->source_dev_id = PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC); + ivhd_ioapic->source_dev_id = PCI_DEVID(0, SMBUS_DEV, SMBUS_FUNC); ivhd_ioapic->variety = IVHD_SPECIAL_DEV_IOAPIC; current += sizeof(ivrs_ivhd_special_t); @@ -189,7 +189,7 @@ static unsigned long acpi_fill_ivrs_ioapic(acpi_ivrs_t *ivrs, unsigned long curr ivhd_ioapic->reserved = 0x0000; ivhd_ioapic->dte_setting = 0x00; ivhd_ioapic->handle = get_ioapic_id((u8 *)IO_APIC2_ADDR); - ivhd_ioapic->source_dev_id = PCI_DEVFN(0, 1); + ivhd_ioapic->source_dev_id = PCI_DEVID(0, 0, 1); ivhd_ioapic->variety = IVHD_SPECIAL_DEV_IOAPIC; current += sizeof(ivrs_ivhd_special_t); @@ -206,7 +206,7 @@ static unsigned long ivhd_describe_hpet(unsigned long current) ivhd_hpet->reserved = 0x0000; ivhd_hpet->dte_setting = 0x00; ivhd_hpet->handle = 0x00; - ivhd_hpet->source_dev_id = PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC); + ivhd_hpet->source_dev_id = PCI_DEVID(0, SMBUS_DEV, SMBUS_FUNC); ivhd_hpet->variety = IVHD_SPECIAL_DEV_HPET; current += sizeof(ivrs_ivhd_special_t); @@ -346,7 +346,7 @@ static unsigned long acpi_fill_ivrs11(unsigned long current, acpi_ivrs_t *ivrs_a ivhd_11->flags = ivrs_agesa->ivhd.flags & 0x3f; ivhd_11->length = sizeof(struct acpi_ivrs_ivhd_11); /* BDF :00.2 */ - ivhd_11->device_id = 0x02 | (nb_dev->upstream->secondary << 8); + ivhd_11->device_id = PCI_DEVID(nb_dev->upstream->secondary, 0, 2); /* PCI Capability block 0x40 (type 0xf, "Secure device") */ ivhd_11->capability_offset = 0x40; ivhd_11->iommu_base_low = ivrs_agesa->ivhd.iommu_base_low; @@ -369,7 +369,7 @@ static unsigned long acpi_fill_ivrs11(unsigned long current, acpi_ivrs_t *ivrs_a /* Now repeat all the device entries from type 10h */ current_backup = current; - current = ivhd_dev_range(current, PCI_DEVFN(1, 0), PCI_DEVFN(0x1f, 6), 0); + current = ivhd_dev_range(current, PCI_DEVID(0, 1, 0), PCI_DEVID(0, 0x1f, 6), 0); ivhd_11->length += (current - current_backup); add_ivhd_device_entries(NULL, all_devices, 0, -1, NULL, ¤t, &ivhd_11->length); @@ -414,7 +414,7 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) ivrs->ivhd.flags = ivrs_agesa->ivhd.flags; ivrs->ivhd.length = sizeof(struct acpi_ivrs_ivhd); /* BDF :00.2 */ - ivrs->ivhd.device_id = 0x02 | (nb_dev->upstream->secondary << 8); + ivrs->ivhd.device_id = PCI_DEVID(nb_dev->upstream->secondary, 0, 2); /* PCI Capability block 0x40 (type 0xf, "Secure device") */ ivrs->ivhd.capability_offset = 0x40; ivrs->ivhd.iommu_base_low = ivrs_agesa->ivhd.iommu_base_low; @@ -437,7 +437,7 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) * translate transactions generated by itself. */ current_backup = current; - current = ivhd_dev_range(current, PCI_DEVFN(1, 0), PCI_DEVFN(0x1f, 6), 0); + current = ivhd_dev_range(current, PCI_DEVID(0, 1, 0), PCI_DEVID(0, 0x1f, 6), 0); ivrs->ivhd.length += (current - current_backup); add_ivhd_device_entries(NULL, all_devices, 0, -1, NULL, ¤t, &ivrs->ivhd.length); From 900e49ab1fdd9e46c6311d088bc14f2c944af808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 11:13:51 +0100 Subject: [PATCH 08/11] src/northbridge/amd/pi/00730F01/northbridge.c: Rework IVRS generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- src/northbridge/amd/pi/00730F01/northbridge.c | 117 +++++------------- 1 file changed, 34 insertions(+), 83 deletions(-) diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 7c874187de0..644e746b713 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -236,89 +236,32 @@ static unsigned long ivhd_dev_range(unsigned long current, uint16_t start_devid, return current; } -static unsigned long add_ivhd_dev_entry(struct device *parent, struct device *dev, - unsigned long *current, uint8_t type, uint8_t data) +static unsigned long ivhd_dev_alias_range(unsigned long current, uint16_t start_devid, + uint16_t end_devid, uint16_t source_devid, + uint8_t setting) { - if (type == IVHD_DEV_4_BYTE_SELECT) { - /* 4-byte IVHD structures must be aligned to the 4-byte boundary. */ - *current = ALIGN_UP(*current, 4); - ivrs_ivhd_generic_t *ivhd_entry = (ivrs_ivhd_generic_t *)*current; - - ivhd_entry->type = type; - ivhd_entry->dev_id = dev->path.pci.devfn | (dev->upstream->secondary << 8); - ivhd_entry->dte_setting = data; - *current += sizeof(ivrs_ivhd_generic_t); - } else if (type == IVHD_DEV_8_BYTE_ALIAS_SELECT) { - /* 8-byte IVHD structures must be aligned to the 8-byte boundary. */ - *current = ALIGN_UP(*current, 8); - ivrs_ivhd_alias_t *ivhd_entry = (ivrs_ivhd_alias_t *)*current; - - ivhd_entry->type = type; - ivhd_entry->dev_id = dev->path.pci.devfn | (dev->upstream->secondary << 8); - ivhd_entry->dte_setting = data; - ivhd_entry->reserved1 = 0; - ivhd_entry->reserved2 = 0; - ivhd_entry->source_dev_id = parent->path.pci.devfn | - (parent->upstream->secondary << 8); - *current += sizeof(ivrs_ivhd_alias_t); - } - - return *current; -} - -static void ivrs_add_device_or_bridge(struct device *parent, struct device *dev, - unsigned long *current, uint16_t *ivhd_length) -{ - unsigned int header_type, is_pcie; - unsigned long current_backup; - - header_type = dev->hdr_type & 0x7f; - is_pcie = pci_find_capability(dev, PCI_CAP_ID_PCIE); - - if (((header_type == PCI_HEADER_TYPE_NORMAL) || - (header_type == PCI_HEADER_TYPE_BRIDGE)) && is_pcie) { - /* Device or Bridge is PCIe */ - current_backup = *current; - add_ivhd_dev_entry(parent, dev, current, IVHD_DEV_4_BYTE_SELECT, 0x0); - *ivhd_length += (*current - current_backup); - } else if ((header_type == PCI_HEADER_TYPE_NORMAL) && !is_pcie) { - /* Device is legacy PCI or PCI-X */ - current_backup = *current; - add_ivhd_dev_entry(parent, dev, current, IVHD_DEV_8_BYTE_ALIAS_SELECT, 0x0); - *ivhd_length += (*current - current_backup); - } -} - -static void add_ivhd_device_entries(struct device *parent, struct device *dev, - unsigned int depth, int linknum, int8_t *root_level, - unsigned long *current, uint16_t *ivhd_length) -{ - struct device *sibling; - - if (!root_level) { - root_level = malloc(sizeof(int8_t)); - *root_level = -1; - } - - if (dev->path.type == DEVICE_PATH_PCI) { - - if ((dev->upstream->secondary == 0x0) && - (dev->path.pci.devfn == 0x0)) - *root_level = depth; + /* 8-byte IVHD structures must be aligned to the 8-byte boundary. */ + current = ALIGN_UP(current, 8); + ivrs_ivhd_alias_t *ivhd_range = (ivrs_ivhd_alias_t *)current; + ivrs_ivhd_generic_t *ivhd_range_end; - if ((*root_level != -1) && (dev->enabled)) { - if (depth != *root_level) - ivrs_add_device_or_bridge(parent, dev, current, ivhd_length); - } - } + /* Create the start alias range IVHD entry */ + ivhd_range->type = IVHD_DEV_8_BYTE_ALIAS_START_RANGE; + ivhd_range->dev_id = start_devid; + ivhd_range->dte_setting = setting; + ivhd_range->source_dev_id = source_devid; + ivhd_range->reserved1 = 0; + ivhd_range->reserved2 = 0; + current += sizeof(ivrs_ivhd_alias_t); - if (dev->downstream) { - for (sibling = dev->downstream->children; sibling; sibling = sibling->sibling) - add_ivhd_device_entries(dev, sibling, depth + 1, depth, root_level, - current, ivhd_length); - } + /* Create the end range IVHD entry */ + ivhd_range_end = (ivrs_ivhd_generic_t *)current; + ivhd_range_end->type = IVHD_DEV_4_BYTE_END_RANGE; + ivhd_range_end->dev_id = end_devid; + ivhd_range_end->dte_setting = setting; + current += sizeof(ivrs_ivhd_generic_t); - free(root_level); + return current; } static unsigned long acpi_fill_ivrs11(unsigned long current, acpi_ivrs_t *ivrs_agesa) @@ -369,9 +312,13 @@ static unsigned long acpi_fill_ivrs11(unsigned long current, acpi_ivrs_t *ivrs_a /* Now repeat all the device entries from type 10h */ current_backup = current; - current = ivhd_dev_range(current, PCI_DEVID(0, 1, 0), PCI_DEVID(0, 0x1f, 6), 0); + current = ivhd_dev_range(current, PCI_DEVID(0, 1, 0), PCI_DEVID(255, 31, 6), 0); + ivhd_11->length += (current - current_backup); + + current_backup = current; + current = ivhd_dev_alias_range(current, PCI_DEVID(255, 0, 0), PCI_DEVID(255, 31, 7), + PCI_DEVID(0, 14, 4), 0); ivhd_11->length += (current - current_backup); - add_ivhd_device_entries(NULL, all_devices, 0, -1, NULL, ¤t, &ivhd_11->length); /* Describe HPET */ current_backup = current; @@ -437,9 +384,13 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) * translate transactions generated by itself. */ current_backup = current; - current = ivhd_dev_range(current, PCI_DEVID(0, 1, 0), PCI_DEVID(0, 0x1f, 6), 0); + current = ivhd_dev_range(current, PCI_DEVID(0, 1, 0), PCI_DEVID(255, 31, 6), 0); + ivrs->ivhd.length += (current - current_backup); + + current_backup = current; + current = ivhd_dev_alias_range(current, PCI_DEVID(255, 0, 0), PCI_DEVID(255, 31, 7), + PCI_DEVID(0, 14, 4), 0); ivrs->ivhd.length += (current - current_backup); - add_ivhd_device_entries(NULL, all_devices, 0, -1, NULL, ¤t, &ivrs->ivhd.length); /* Describe HPET */ current_backup = current; From 97ab6bb15664caf685bd8b38731c8e2c29f1971f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 15:00:49 +0100 Subject: [PATCH 09/11] northbridge/amd/pi/00730F01/northbridge.c: Soft reserve CC6 save state area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the IORESOURCE_SOFT_RESERVE attribute to reserve CC6 save state DRAM. Using regualr reserved memory makes it hard on EDK2 to detect if it is MMIO or reserved DRAM, as TOM2 is equal to the base of the CC6 save state area, not its limit. Signed-off-by: Michał Żygowski --- src/northbridge/amd/pi/00730F01/northbridge.c | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 644e746b713..02dbb3a99e8 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -50,6 +50,16 @@ static int get_dram_base_limit(resource_t *basek, resource_t *limitk) return 1; } +static void get_dram_limit_sys(resource_t *limitk) +{ + u32 temp = pci_read_config32(DEV_PTR(ht_1), 0x124); //[47:27] at [20:0] + /* BKDG address[47:0] <= {DramLimitAddr[47:27], 7FF_FFFFh} */ + *limitk = (resource_t)(temp & 0x1fffff) << 27; + *limitk |= 0x7ffffff; + *limitk += 1; // round up last byte + *limitk = *limitk >> 10; +} + static void add_fixed_resources(struct device *dev, int index) { /* Reserve everything between A segment and 1MB: @@ -62,11 +72,11 @@ static void add_fixed_resources(struct device *dev, int index) /* Check if CC6 save area is enabled (bit 18 CC6SaveEn) */ if (pci_read_config32(DEV_PTR(ht_2), 0x118) & (1 << 18)) { - /* Add CC6 DRAM UC resource residing at DRAM Limit of size 16MB as per BKDG */ - resource_t basek, limitk; - if (!get_dram_base_limit(&basek, &limitk)) - return; - mmio_resource_kb(dev, index++, limitk, 16 * 1024); + /* Add CC6 DRAM UC resource residing at DRAM Sys Limit - 16MB as per BKDG */ + resource_t limitk; + get_dram_limit_sys(&limitk); + fixed_mem_resource_kb(dev, index++, limitk - 16 * 1024, 16 * 1024, + IORESOURCE_SOFT_RESERVE); } } From acc4e716181c593f49bdb8bf9bfb5b5fee8e5e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 18:30:50 +0100 Subject: [PATCH 10/11] configs/config.pcengines_uefi_apu: Bump edk2 revision to fix IOMMU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- configs/config.pcengines_uefi_apu2 | 2 +- configs/config.pcengines_uefi_apu3 | 2 +- configs/config.pcengines_uefi_apu4 | 2 +- configs/config.pcengines_uefi_apu6 | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/config.pcengines_uefi_apu2 b/configs/config.pcengines_uefi_apu2 index 39279845fdd..55b89a7d19b 100644 --- a/configs/config.pcengines_uefi_apu2 +++ b/configs/config.pcengines_uefi_apu2 @@ -20,7 +20,7 @@ CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y # CONFIG_CONSOLE_USE_ANSI_ESCAPES is not set CONFIG_PAYLOAD_EDK2=y CONFIG_EDK2_REPOSITORY="https://github.com/Dasharo/edk2.git" -CONFIG_EDK2_TAG_OR_REV="f3e18c6cd9c9afb15b83edf9b88c76e5898dbd88" +CONFIG_EDK2_TAG_OR_REV="bbfa2d3c73ea62946182879a8ed84b84fe779063" CONFIG_EDK2_USE_EDK2_PLATFORMS=y CONFIG_EDK2_PLATFORMS_REPOSITORY="https://github.com/Dasharo/edk2-platforms" CONFIG_EDK2_PLATFORMS_TAG_OR_REV="3323ed481d35096fb6a7eae7b49f35eff00f86cf" diff --git a/configs/config.pcengines_uefi_apu3 b/configs/config.pcengines_uefi_apu3 index 9b9d767fb1a..3bf92df1df0 100644 --- a/configs/config.pcengines_uefi_apu3 +++ b/configs/config.pcengines_uefi_apu3 @@ -21,7 +21,7 @@ CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y # CONFIG_CONSOLE_USE_ANSI_ESCAPES is not set CONFIG_PAYLOAD_EDK2=y CONFIG_EDK2_REPOSITORY="https://github.com/Dasharo/edk2.git" -CONFIG_EDK2_TAG_OR_REV="f3e18c6cd9c9afb15b83edf9b88c76e5898dbd88" +CONFIG_EDK2_TAG_OR_REV="bbfa2d3c73ea62946182879a8ed84b84fe779063" CONFIG_EDK2_USE_EDK2_PLATFORMS=y CONFIG_EDK2_PLATFORMS_REPOSITORY="https://github.com/Dasharo/edk2-platforms" CONFIG_EDK2_PLATFORMS_TAG_OR_REV="3323ed481d35096fb6a7eae7b49f35eff00f86cf" diff --git a/configs/config.pcengines_uefi_apu4 b/configs/config.pcengines_uefi_apu4 index 46727b004f9..82caf91ee24 100644 --- a/configs/config.pcengines_uefi_apu4 +++ b/configs/config.pcengines_uefi_apu4 @@ -21,7 +21,7 @@ CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y # CONFIG_CONSOLE_USE_ANSI_ESCAPES is not set CONFIG_PAYLOAD_EDK2=y CONFIG_EDK2_REPOSITORY="https://github.com/Dasharo/edk2.git" -CONFIG_EDK2_TAG_OR_REV="f3e18c6cd9c9afb15b83edf9b88c76e5898dbd88" +CONFIG_EDK2_TAG_OR_REV="bbfa2d3c73ea62946182879a8ed84b84fe779063" CONFIG_EDK2_USE_EDK2_PLATFORMS=y CONFIG_EDK2_PLATFORMS_REPOSITORY="https://github.com/Dasharo/edk2-platforms" CONFIG_EDK2_PLATFORMS_TAG_OR_REV="3323ed481d35096fb6a7eae7b49f35eff00f86cf" diff --git a/configs/config.pcengines_uefi_apu6 b/configs/config.pcengines_uefi_apu6 index 3a90f765ab2..2f7a821ba10 100644 --- a/configs/config.pcengines_uefi_apu6 +++ b/configs/config.pcengines_uefi_apu6 @@ -21,7 +21,7 @@ CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y # CONFIG_CONSOLE_USE_ANSI_ESCAPES is not set CONFIG_PAYLOAD_EDK2=y CONFIG_EDK2_REPOSITORY="https://github.com/Dasharo/edk2.git" -CONFIG_EDK2_TAG_OR_REV="f3e18c6cd9c9afb15b83edf9b88c76e5898dbd88" +CONFIG_EDK2_TAG_OR_REV="bbfa2d3c73ea62946182879a8ed84b84fe779063" CONFIG_EDK2_USE_EDK2_PLATFORMS=y CONFIG_EDK2_PLATFORMS_REPOSITORY="https://github.com/Dasharo/edk2-platforms" CONFIG_EDK2_PLATFORMS_TAG_OR_REV="3323ed481d35096fb6a7eae7b49f35eff00f86cf" From e4edecadfc5491baf0453469072a88fab035c52f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 27 Nov 2024 00:13:07 +0100 Subject: [PATCH 11/11] nb/amd/pi/00730F01,dsdt_top: Add hook for _PIC method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per family 16h models 30h-3fh BKDG the IoapicSbFeatureEn must be configured according to the interrupt routing mode selecte by OS. If OS chose APIC mode, the IoapicSbFeatureEn must be cleared. Otherwise, it must be set, meaning PIC mode is used. Add a hook to _PIC method to call SoC/northbridge specific code to set/clear the bit to configure GNB IOAPIC properly. ACPI specification says that _PIC method is optional and can be called by OSPM to provide the interrupt routing mode information to the firmware. However, if the method is not called, the firmware must assume PIC mode is used. AGESA sets the IoapicSbFeatureEn already to be compliant with ACPI. Previously, coreboot cleared the bit unconditionally and left a comment to move that part to DSDT. The hook allows to clear the IoapicSbFeatureEn bit if OS chooses APIC mode for interrupt routing. Signed-off-by: Michał Żygowski --- src/acpi/dsdt_top.asl | 7 +++++ .../amd/pi/00730F01/acpi/northbridge.asl | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/acpi/dsdt_top.asl b/src/acpi/dsdt_top.asl index 7539f00e571..568dde94785 100644 --- a/src/acpi/dsdt_top.asl +++ b/src/acpi/dsdt_top.asl @@ -7,6 +7,8 @@ #include #endif +External (\_SB.PCI0.NAPE, MethodObj) + /* Operating system enumeration. */ Name (OSYS, 0) @@ -28,6 +30,11 @@ Method (_PIC, 1) { /* Remember the OS' IRQ routing choice. */ PICM = Arg0 + + If (CondRefOf (\_SB.PCI0.NAPE)) + { + \_SB.PCI0.NAPE(Arg0 & 1) + } } #if CONFIG(ECAM_MMCONF_SUPPORT) diff --git a/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl b/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl index df6aea063be..6ac0a53d9d4 100644 --- a/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl +++ b/src/northbridge/amd/pi/00730F01/acpi/northbridge.asl @@ -6,6 +6,36 @@ External (TOM2) Name(_HID, EISAID("PNP0A08")) /* PCI Express Root Bridge */ Name(_CID, EISAID("PNP0A03")) /* PCI Root Bridge */ +OperationRegion (NAPC, PCI_Config, 0xF8, 0x08) +Field (NAPC, DWordAcc, NoLock, Preserve) +{ + NAPX, 32, /* Northbridge IOAPIC Index */ + NAPD, 32 /* Northbridge IOAPIC Data */ +} + +IndexField (NAPX, NAPD, DWordAcc, NoLock, Preserve) +{ + NAFC, 32 /* Northbridge IOAPIC Feature Control */ +} + +Mutex (NAPM, 0x00) +Method (NAPE, 1, NotSerialized) +{ + Acquire (NAPM, 0xFFFF) + + Local0 = NAFC + Local0 &= 0xFFFFFFEF /* Clear IoapicSbFeatureEn for APIC mode */ + + /* Set IoapicSbFeatureEn if OS chose to use PIC mode */ + If (Arg0 == 0) { + Local0 |= (1 << 4) + } + + NAFC = Local0 + + Release (NAPM) +} + /* Describe the Northbridge devices */ Method(_BBN, 0, NotSerialized) /* Bus number = 0 */