Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/80362?usp=email )
Change subject: soc/intel/cmn/sa: Add APIs into System Agent (SA) common code ......................................................................
soc/intel/cmn/sa: Add APIs into System Agent (SA) common code
This commit streamlines code and strengthens common code robustness by moving the following SoC-layer functions to the common layer:
- sa_get_mmcfg_size: Retrieves the MMIO (Memory-Mapped I/O) configuration space size by reading offset 0x60 of the PCI Host Bridge (D0:F0). - sa_get_dsm_size: Calculates the size of the DSM (Device Stolen Memory) by reading offset 0x50 of the PCI Host Bridge (D0:F0) to determine pre-allocated memory for the IGD (Integrated Graphics Device). - sa_get_gsm_size: Calculates the size of the GSM (Graphics Stolen Memory) by reading offset 0x52 of the PCI Host Bridge (D0:F0). - sa_get_dpr_size: Determines the size of the DMA Protection Range (DPR) by reading offset 0x5C of the PCI Host Bridge (D0:F0).
TEST= Build and boot successful on google/screebo.
Change-Id: Ic00e001563ec6f0d737a445964c716b45db43327 Signed-off-by: Subrata Banik subratabanik@google.com --- M src/soc/intel/common/block/include/intelblocks/systemagent.h M src/soc/intel/common/block/systemagent/systemagent.c M src/soc/intel/common/block/systemagent/systemagent_def.h 3 files changed, 131 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/62/80362/1
diff --git a/src/soc/intel/common/block/include/intelblocks/systemagent.h b/src/soc/intel/common/block/include/intelblocks/systemagent.h index d817e9c..deeedb6 100644 --- a/src/soc/intel/common/block/include/intelblocks/systemagent.h +++ b/src/soc/intel/common/block/include/intelblocks/systemagent.h @@ -99,6 +99,14 @@ size_t sa_get_tseg_size(void); /* API to lock PAM registers */ void sa_lock_pam(void); +/* API to get MMIO config size */ +uint64_t sa_get_mmcfg_size(const struct device *dev); +/* API to get DSM size */ +uint64_t sa_get_dsm_size(const struct device *dev); +/* API to get GSM size */ +uint64_t sa_get_gsm_size(const struct device *dev); +/* API to get DPR size */ +uint64_t sa_get_dpr_size(const struct device *dev);
/* * SoC overrides diff --git a/src/soc/intel/common/block/systemagent/systemagent.c b/src/soc/intel/common/block/systemagent/systemagent.c index c2d561a..576dbfc 100644 --- a/src/soc/intel/common/block/systemagent/systemagent.c +++ b/src/soc/intel/common/block/systemagent/systemagent.c @@ -324,6 +324,120 @@ printk(BIOS_DEBUG, "PCI space above 4GB MMIO is at 0x%llx, len = 0x%llx\n", touud, len); }
+uint64_t sa_get_mmcfg_size(const struct device *dev) +{ + uint32_t pciexbar_reg; + uint64_t mmcfg_length; + + if (!dev) { + printk(BIOS_DEBUG, "%s : device is null\n", __func__); + return 0; + } + + pciexbar_reg = pci_read_config32(dev, PCIEXBAR); + + if (!(pciexbar_reg & (1 << 0))) { + printk(BIOS_DEBUG, "%s : PCIEXBAR disabled\n", __func__); + return 0; + } + + switch ((pciexbar_reg & MASK_PCIEXBAR_LENGTH) >> PCIEXBAR_LENGTH_LSB) { + case PCIEXBAR_LENGTH_4096MB: + mmcfg_length = 4 * ((uint64_t)GiB); + break; + case PCIEXBAR_LENGTH_2048MB: + mmcfg_length = 2 * ((uint64_t)GiB); + break; + case PCIEXBAR_LENGTH_1024MB: + mmcfg_length = 1 * GiB; + break; + case PCIEXBAR_LENGTH_512MB: + mmcfg_length = 512 * MiB; + break; + case PCIEXBAR_LENGTH_256MB: + mmcfg_length = 256 * MiB; + break; + case PCIEXBAR_LENGTH_128MB: + mmcfg_length = 128 * MiB; + break; + case PCIEXBAR_LENGTH_64MB: + mmcfg_length = 64 * MiB; + break; + default: + printk(BIOS_DEBUG, "%s : PCIEXBAR - invalid length (0x%x)\n", __func__, + pciexbar_reg & MASK_PCIEXBAR_LENGTH); + mmcfg_length = 0x0; + break; + } + + return mmcfg_length; +} + +uint64_t sa_get_dsm_size(const struct device *dev) +{ + // - size : B0/D0/F0:R 50h [15:8] + uint32_t reg32 = pci_read_config32(dev, GGC); + uint64_t size; + uint32_t size_field = (reg32 & MASK_DSM_LENGTH) >> MASK_DSM_LENGTH_LSB; + if (size_field <= 0x10) { // 0x0 - 0x10 + size = size_field * 32 * MiB; + } else if ((size_field >= 0xF0) && (size_field >= 0xFE)) { + size = ((uint64_t)size_field - 0xEF) * 4 * MiB; + } else { + switch (size_field) { + case 0x20: + size = 1 * GiB; + break; + case 0x30: + size = 1536 * MiB; + break; + case 0x40: + size = 2 * (uint64_t)GiB; + break; + default: + printk(BIOS_DEBUG, "%s : DSM - invalid length (0x%x)\n", + __func__, size_field); + size = 0x0; + break; + } + } + return size; +} + +uint64_t sa_get_gsm_size(const struct device *dev) +{ + const u32 gsm_size = pci_read_config32(dev, GGC); + uint64_t size; + uint32_t size_field = (gsm_size & MASK_GSM_LENGTH) >> MASK_GSM_LENGTH_LSB; + switch (size_field) { + case 0x0: + size = 0; + break; + case 0x1: + size = 2 * MiB; + break; + case 0x2: + size = 4 * MiB; + break; + case 0x3: + size = 8 * MiB; + break; + default: + size = 0; + break; + } + return size; +} + +uint64_t sa_get_dpr_size(const struct device *dev) +{ + uint64_t size; + uint32_t dpr_reg = pci_read_config32(dev, DPR); + uint32_t size_field = (dpr_reg & MASK_DPR_LENGTH) >> MASK_DPR_LENGTH_LSB; + size = (uint64_t)size_field * MiB; + return size; +} + struct device_operations systemagent_ops = { .read_resources = systemagent_read_resources, .set_resources = pci_dev_set_resources, diff --git a/src/soc/intel/common/block/systemagent/systemagent_def.h b/src/soc/intel/common/block/systemagent/systemagent_def.h index f913843..bfeaca4 100644 --- a/src/soc/intel/common/block/systemagent/systemagent_def.h +++ b/src/soc/intel/common/block/systemagent/systemagent_def.h @@ -29,6 +29,15 @@ /* Device 0:0.0 MMIO space */ #define MCH_PAIR 0x5418
+#define MASK_PCIEXBAR_LENGTH 0x0000000E /* bits 1-3 */ +#define PCIEXBAR_LENGTH_LSB 1 /* used to shift right */ +#define MASK_DSM_LENGTH 0xFF00 /* bits 8-15 */ +#define MASK_DSM_LENGTH_LSB 8 /* used to shift right */ +#define MASK_GSM_LENGTH 0xC0 /* bits 6-7 */ +#define MASK_GSM_LENGTH_LSB 6 /* used to shift right */ +#define MASK_DPR_LENGTH 0xFF0 /* bits 4-11 */ +#define MASK_DPR_LENGTH_LSB 4 /* used to shift right */ + /* * IMR register in case CONFIG(SA_ENABLE_IMR) is selected by SoC. *