soc/intel/xeon_sp/uncore.c: Add CXL memory into memory map

If the host supports CXL, get proximity domain info from FSP HOB. The
proximity domains may include both processor domains and CXL domains.

Add header definition for proximity domain.

Add CXL memory into memory map.

Change-Id: If3f856958a3e6ed3909240ee455bb639e487087f
Signed-off-by: Jonathan Zhang <jonzhang@meta.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/72617
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
diff --git a/src/soc/intel/xeon_sp/uncore.c b/src/soc/intel/xeon_sp/uncore.c
index 418736e..5249a94 100644
--- a/src/soc/intel/xeon_sp/uncore.c
+++ b/src/soc/intel/xeon_sp/uncore.c
@@ -5,6 +5,7 @@
 #include <cpu/x86/lapic_def.h>
 #include <device/pci.h>
 #include <device/pci_ids.h>
+#include <drivers/ocp/include/vpd.h>
 #include <soc/acpi.h>
 #include <soc/iomap.h>
 #include <soc/pci_devs.h>
@@ -13,8 +14,15 @@
 #include <fsp/util.h>
 #include <security/intel/txt/txt_platform.h>
 #include <security/intel/txt/txt.h>
+#include <soc/numa.h>
+#include <soc/soc_util.h>
 #include <stdint.h>
 
+struct proximity_domains pds = {
+	.num_pds = 0,
+	.pds = NULL,
+};
+
 struct map_entry {
 	uint32_t    reg;
 	int         is_64_bit;
@@ -238,9 +246,42 @@
 				   mc_values[TOLM_REG]);
 	LOG_RESOURCE("mmio_tolm", dev, res);
 
-	/* 4GiB -> TOHM */
-	res = upper_ram_end(dev, index++, mc_values[TOHM_REG] + 1);
-	LOG_RESOURCE("high_ram", dev, res);
+	if (CONFIG(SOC_INTEL_HAS_CXL)) {
+		/* 4GiB -> CXL Memory */
+		uint32_t gi_mem_size;
+		gi_mem_size = get_generic_initiator_mem_size();
+
+		res = reserved_ram_from_to(dev, index++, 0x100000000,
+				   mc_values[TOHM_REG] - (uint64_t)gi_mem_size + 1);
+		LOG_RESOURCE("high_ram", dev, res);
+
+		/* CXL Memory */
+		uint8_t i;
+		for (i = 0; i < pds.num_pds; i++) {
+			if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR)
+				continue;
+
+			if (CONFIG(OCP_VPD)) {
+				unsigned long flags = IORESOURCE_CACHEABLE;
+				int cxl_mode = get_cxl_mode_from_vpd();
+				if (cxl_mode == CXL_SPM)
+					flags |= IORESOURCE_SOFT_RESERVE;
+				else
+					flags |= IORESOURCE_STORED;
+
+				res = fixed_mem_range_flags(dev, index++, (uint64_t)pds.pds[i].base,
+					(uint64_t)pds.pds[i].size, flags);
+				if (cxl_mode == CXL_SPM)
+					LOG_RESOURCE("specific_purpose_memory", dev, res);
+				else
+					LOG_RESOURCE("CXL_memory", dev, res);
+			}
+		}
+	} else {
+		/* 4GiB -> TOHM */
+		res = upper_ram_end(dev, index++, mc_values[TOHM_REG] + 1);
+		LOG_RESOURCE("high_ram", dev, res);
+	}
 
 	/* add MMIO CFG resource */
 	res = mmio_from_to(dev, index++, mc_values[MMCFG_BASE_REG],
@@ -271,6 +312,14 @@
 {
 	int index = 0;
 
+	if (CONFIG(SOC_INTEL_HAS_CXL)) {
+		/* Construct NUMA data structure. This is needed for CXL. */
+		if (fill_pds() != CB_SUCCESS)
+			pds.num_pds = 0;
+
+		dump_pds();
+	}
+
 	/* Read standard PCI resources. */
 	pci_dev_read_resources(dev);