soc/amd/common/data_fabric: add support for extended MMIO addresses
The Genoa SoC supports MMIO addresses larger than 48 bits. Since the MMIO base and limit registers in the data fabric only contain bits 16 to 47 of the MMIO address, the MMIO address extension register is introduced on some SoCs like Genoa. This additional register contains the upper bits of the MMIO base and limit. Since it's not available on all SoCs, introduce the SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO Kconfig option to select the correct data_fabric_get_mmio_base_size implementation to be added to the build. Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: Ic304f5797bc5661c1d511c95e457c6dde169d329 Reviewed-on: https://review.coreboot.org/c/coreboot/+/77514 Reviewed-by: Martin Roth <martin.roth@amd.corp-partner.google.com> Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Varshit Pandya <pandyavarshit@gmail.com>
This commit is contained in:
parent
a637fa9310
commit
7cdc4296f0
|
@ -24,3 +24,12 @@ config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_MULTI_PCI_SEGMENT
|
||||||
the PCI bus number which includes the segment number must select this
|
the PCI bus number which includes the segment number must select this
|
||||||
option; SoCs that use one data fabric register for the PCI bus number
|
option; SoCs that use one data fabric register for the PCI bus number
|
||||||
which doesn't include a segment number field mustn't select this.
|
which doesn't include a segment number field mustn't select this.
|
||||||
|
|
||||||
|
config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO
|
||||||
|
bool
|
||||||
|
depends on SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
|
||||||
|
help
|
||||||
|
Some AMD SoCs support more than 48 bit MMIO addresses. In order to
|
||||||
|
have enough bits for this, the MMIO address extension register is
|
||||||
|
introduced. SoCs that have this register must select this option in
|
||||||
|
order for the MMIO regions to be reported correctly.
|
||||||
|
|
|
@ -8,3 +8,9 @@ ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += pci_segment_multi.
|
||||||
else
|
else
|
||||||
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += pci_segment_single.c
|
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += pci_segment_single.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO),y)
|
||||||
|
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += extended_mmio.c
|
||||||
|
else
|
||||||
|
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN) += mmio.c
|
||||||
|
endif
|
||||||
|
|
|
@ -36,17 +36,6 @@ void amd_pci_domain_scan_bus(struct device *domain)
|
||||||
pci_domain_scan_bus(domain);
|
pci_domain_scan_bus(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the registers and return normalized values */
|
|
||||||
static void data_fabric_get_mmio_base_size(unsigned int reg,
|
|
||||||
resource_t *mmio_base, resource_t *mmio_limit)
|
|
||||||
{
|
|
||||||
const uint32_t base_reg = data_fabric_broadcast_read32(DF_MMIO_BASE(reg));
|
|
||||||
const uint32_t limit_reg = data_fabric_broadcast_read32(DF_MMIO_LIMIT(reg));
|
|
||||||
/* The raw register values are bits 47..16 of the actual address */
|
|
||||||
*mmio_base = (resource_t)base_reg << DF_MMIO_SHIFT;
|
|
||||||
*mmio_limit = (((resource_t)limit_reg + 1) << DF_MMIO_SHIFT) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_df_mmio_outside_of_cpu_mmio_error(unsigned int reg)
|
static void print_df_mmio_outside_of_cpu_mmio_error(unsigned int reg)
|
||||||
{
|
{
|
||||||
printk(BIOS_WARNING, "DF MMIO register %u outside of CPU MMIO region.\n", reg);
|
printk(BIOS_WARNING, "DF MMIO register %u outside of CPU MMIO region.\n", reg);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <amdblocks/data_fabric.h>
|
||||||
|
#include <device/device.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
/* Read the registers and return normalized values */
|
||||||
|
void data_fabric_get_mmio_base_size(unsigned int reg, resource_t *mmio_base,
|
||||||
|
resource_t *mmio_limit)
|
||||||
|
{
|
||||||
|
const uint32_t base_reg = data_fabric_broadcast_read32(DF_MMIO_BASE(reg));
|
||||||
|
const uint32_t limit_reg = data_fabric_broadcast_read32(DF_MMIO_LIMIT(reg));
|
||||||
|
const union df_mmio_addr_ext ext_reg.raw =
|
||||||
|
data_fabric_broadcast_read32(DF_MMIO_ADDR_EXT(reg));
|
||||||
|
/* The raw register values in the base and limit registers are bits 47..16 of the
|
||||||
|
actual address. The MMIO address extension register contains the extended MMIO base
|
||||||
|
and limit bits starting with bit 48 of the actual address. */
|
||||||
|
*mmio_base = (resource_t)ext_reg.base_ext << DF_MMIO_EXT_ADDR_SHIFT |
|
||||||
|
(resource_t)base_reg << DF_MMIO_SHIFT;
|
||||||
|
*mmio_limit = (resource_t)ext_reg.limit_ext << DF_MMIO_EXT_ADDR_SHIFT |
|
||||||
|
(((resource_t)limit_reg + 1) << DF_MMIO_SHIFT) - 1;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <amdblocks/data_fabric.h>
|
||||||
|
#include <device/device.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
/* Read the registers and return normalized values */
|
||||||
|
void data_fabric_get_mmio_base_size(unsigned int reg, resource_t *mmio_base,
|
||||||
|
resource_t *mmio_limit)
|
||||||
|
{
|
||||||
|
const uint32_t base_reg = data_fabric_broadcast_read32(DF_MMIO_BASE(reg));
|
||||||
|
const uint32_t limit_reg = data_fabric_broadcast_read32(DF_MMIO_LIMIT(reg));
|
||||||
|
/* The raw register values are bits 47..16 of the actual address */
|
||||||
|
*mmio_base = (resource_t)base_reg << DF_MMIO_SHIFT;
|
||||||
|
*mmio_limit = (((resource_t)limit_reg + 1) << DF_MMIO_SHIFT) - 1;
|
||||||
|
}
|
|
@ -22,6 +22,9 @@
|
||||||
#define DF_MMIO_BASE(reg) (DF_MMIO_BASE0 + DF_MMIO_REG_OFFSET(reg))
|
#define DF_MMIO_BASE(reg) (DF_MMIO_BASE0 + DF_MMIO_REG_OFFSET(reg))
|
||||||
#define DF_MMIO_LIMIT(reg) (DF_MMIO_LIMIT0 + DF_MMIO_REG_OFFSET(reg))
|
#define DF_MMIO_LIMIT(reg) (DF_MMIO_LIMIT0 + DF_MMIO_REG_OFFSET(reg))
|
||||||
#define DF_MMIO_CONTROL(reg) (DF_MMIO_CTRL0 + DF_MMIO_REG_OFFSET(reg))
|
#define DF_MMIO_CONTROL(reg) (DF_MMIO_CTRL0 + DF_MMIO_REG_OFFSET(reg))
|
||||||
|
#if CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO)
|
||||||
|
#define DF_MMIO_ADDR_EXT(reg) (DF_MMIO_ADDR_EXT0 + DF_MMIO_REG_OFFSET(reg))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Last 12GB of the usable address space are reserved */
|
/* Last 12GB of the usable address space are reserved */
|
||||||
#define DF_RESERVED_TOP_12GB_MMIO_SIZE (12ULL * GiB)
|
#define DF_RESERVED_TOP_12GB_MMIO_SIZE (12ULL * GiB)
|
||||||
|
@ -51,6 +54,9 @@ void data_fabric_set_mmio_np(void);
|
||||||
enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *first_bus,
|
enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *first_bus,
|
||||||
uint8_t *last_bus);
|
uint8_t *last_bus);
|
||||||
|
|
||||||
|
void data_fabric_get_mmio_base_size(unsigned int reg, resource_t *mmio_base,
|
||||||
|
resource_t *mmio_limit);
|
||||||
|
|
||||||
/* Inform the resource allocator about the usable IO and MMIO regions and PCI bus numbers */
|
/* Inform the resource allocator about the usable IO and MMIO regions and PCI bus numbers */
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue