summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorShuo Liu <shuo.liu@intel.com>2024-03-18 00:42:42 +0800
committerLean Sheng Tan <sheng.tan@9elements.com>2024-05-14 20:49:04 +0000
commita5487ba17ad1a531108abd6e9d468cf6645ba53e (patch)
tree075323bbf940041bbb06d31ebb4bb7ffe2066886 /src/soc
parented366c07bb95681906c2092c9714289736accd9d (diff)
soc/intel/xeon_sp: Add Granite Rapids initial codes
coreboot GNR (Granite Rapids) is a FSP 2.4 based, no-PCH, single IO-APIC Xeon-SP platform. The same set of codes is also used for SRF (Sierra Forest) SoC. This patch initially sets the code set up as a build target with Granite Rapids N-1 FSP (src/vc/intel/fsp/fsp2_0/graniterapids). 1. All register definitions are forked from SPR (Sapphire Rapids) and EBG (Emmitsburg PCH)'s codes are reused. 2. src/soc/intel/xeon_sp/chip_gen6.c is newly added as chip common codes for 6th Gen Xeon-SP SoC (Granite Rapids) and later. Change-Id: I3084e1b5abf25d8d9504bebeaed2a15b916ed56b Signed-off-by: Shuo Liu <shuo.liu@intel.com> Co-authored-by: Gang Chen <gang.c.chen@intel.com> Co-authored-by: Jincheng Li <jincheng.li@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81316 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/xeon_sp/Makefile.mk2
-rw-r--r--src/soc/intel/xeon_sp/chip_gen6.c98
-rw-r--r--src/soc/intel/xeon_sp/gnr/Kconfig130
-rw-r--r--src/soc/intel/xeon_sp/gnr/Makefile.mk28
-rw-r--r--src/soc/intel/xeon_sp/gnr/acpi/gpe.asl34
-rw-r--r--src/soc/intel/xeon_sp/gnr/chip.c59
-rw-r--r--src/soc/intel/xeon_sp/gnr/chip.h32
-rw-r--r--src/soc/intel/xeon_sp/gnr/chipset.cb21
-rw-r--r--src/soc/intel/xeon_sp/gnr/cpu.c106
-rw-r--r--src/soc/intel/xeon_sp/gnr/include/soc/cpu.h9
-rw-r--r--src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h201
-rw-r--r--src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h64
-rw-r--r--src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h31
-rw-r--r--src/soc/intel/xeon_sp/gnr/ramstage.c9
-rw-r--r--src/soc/intel/xeon_sp/gnr/romstage.c53
-rw-r--r--src/soc/intel/xeon_sp/gnr/soc_acpi.c41
-rw-r--r--src/soc/intel/xeon_sp/gnr/soc_util.c150
17 files changed, 1068 insertions, 0 deletions
diff --git a/src/soc/intel/xeon_sp/Makefile.mk b/src/soc/intel/xeon_sp/Makefile.mk
index 18a53acc50..3ebc6e0c4a 100644
--- a/src/soc/intel/xeon_sp/Makefile.mk
+++ b/src/soc/intel/xeon_sp/Makefile.mk
@@ -5,6 +5,8 @@ ifeq ($(CONFIG_XEON_SP_COMMON_BASE),y)
subdirs-$(CONFIG_SOC_INTEL_SKYLAKE_SP) += skx lbg
subdirs-$(CONFIG_SOC_INTEL_COOPERLAKE_SP) += cpx lbg
subdirs-$(CONFIG_SOC_INTEL_SAPPHIRERAPIDS_SP) += spr ebg
+## TODO: GNR IBL codes are initially reused from EBG, will update later.
+subdirs-$(CONFIG_SOC_INTEL_GRANITERAPIDS) += gnr ebg
bootblock-y += bootblock.c spi.c lpc.c pch.c report_platform.c
romstage-y += romstage.c reset.c util.c spi.c pmutil.c memmap.c ddr.c
diff --git a/src/soc/intel/xeon_sp/chip_gen6.c b/src/soc/intel/xeon_sp/chip_gen6.c
new file mode 100644
index 0000000000..a1b1b6504f
--- /dev/null
+++ b/src/soc/intel/xeon_sp/chip_gen6.c
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpigen_pci.h>
+#include <assert.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <intelblocks/acpi.h>
+#include <post.h>
+#include <soc/acpi.h>
+#include <soc/chip_common.h>
+#include <soc/numa.h>
+#include <soc/soc_util.h>
+#include <soc/util.h>
+#include <stdlib.h>
+
+static const UDS_PCIROOT_RES *domain_to_pciroot_res(const struct device *dev)
+{
+ assert(dev->path.type == DEVICE_PATH_DOMAIN);
+ const union xeon_domain_path dn = {
+ .domain_path = dev->path.domain.domain
+ };
+
+ const IIO_UDS *hob = get_iio_uds();
+ assert(hob != NULL);
+
+ const UDS_STACK_RES *sr = &hob->PlatformData.IIO_resource[dn.socket].StackRes[dn.stack];
+ for (unsigned int index = 0; index < sr->PciRootBridgeNum; index++) {
+ if (sr->PciRoot[index].BusBase == dev->downstream->secondary)
+ return &sr->PciRoot[index];
+ }
+
+ return NULL;
+}
+
+static void iio_pci_domain_read_resources(struct device *dev)
+{
+ int index = 0;
+ struct resource *res;
+ const UDS_PCIROOT_RES *pr = domain_to_pciroot_res(dev);
+
+ /* Initialize the system-wide I/O space constraints. */
+ if (pr->IoBase <= pr->IoLimit) {
+ res = new_resource(dev, index++);
+ res->base = pr->IoBase;
+ res->limit = pr->IoLimit;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED;
+ }
+
+ /* The 0 - 0xfff IO range is not reported by the HOB but still gets decoded */
+ if (is_domain0(dev)) {
+ res = new_resource(dev, index++);
+ res->base = 0;
+ res->limit = 0xfff;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+ }
+
+ /* Initialize the system-wide memory resources constraints. */
+ if (pr->Mmio32Base <= pr->Mmio32Limit) {
+ res = new_resource(dev, index++);
+ res->base = pr->Mmio32Base;
+ res->limit = pr->Mmio32Limit;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
+ }
+
+ /* Initialize the system-wide memory resources constraints. */
+ if (pr->Mmio64Base <= pr->Mmio64Limit) {
+ res = new_resource(dev, index++);
+ res->base = pr->Mmio64Base;
+ res->limit = pr->Mmio64Limit;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
+ }
+}
+
+static struct device_operations iio_pcie_domain_ops = {
+ .read_resources = iio_pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .scan_bus = pci_host_bridge_scan_bus,
+#if CONFIG(HAVE_ACPI_TABLES)
+ .acpi_name = soc_acpi_name,
+ .write_acpi_tables = northbridge_write_acpi_tables,
+ .acpi_fill_ssdt = pci_domain_fill_ssdt,
+#endif
+};
+
+void create_xeonsp_domains(const union xeon_domain_path dp, struct bus *bus,
+ const xSTACK_RES *sr, const size_t pci_segment_group)
+{
+ for (unsigned int index = 0; index < sr->PciRootBridgeNum; index++) {
+ const UDS_PCIROOT_RES *pr = &sr->PciRoot[index];
+ create_domain(dp, bus,
+ pr->BusBase,
+ pr->BusLimit,
+ pciroot_res_to_domain_type(sr, pr),
+ &iio_pcie_domain_ops,
+ pci_segment_group);
+ }
+}
diff --git a/src/soc/intel/xeon_sp/gnr/Kconfig b/src/soc/intel/xeon_sp/gnr/Kconfig
new file mode 100644
index 0000000000..abbf178edc
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/Kconfig
@@ -0,0 +1,130 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+config SOC_INTEL_GRANITERAPIDS
+ bool
+ select MICROCODE_BLOB_NOT_HOOKED_UP
+ select FSP_NVS_DATA_POST_SILICON_INIT
+ select SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION
+ select XEON_SP_COMMON_BASE
+ select PLATFORM_USES_FSP2_4
+ select CACHE_MRC_SETTINGS
+ select CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
+ select XEON_SP_IBL
+ select DEFAULT_X2APIC_RUNTIME
+ select UDK_202302_BINDING
+ select PLATFORM_USES_FSP2_X86_32
+ select HAVE_IOAT_DOMAINS
+ select FSP_SPEC_VIOLATION_XEON_SP_HEAP_WORKAROUND
+ select VPD
+ help
+ Intel Granite Rapids support
+
+if SOC_INTEL_GRANITERAPIDS
+
+config CHIPSET_DEVICETREE
+ string
+ default "soc/intel/xeon_sp/gnr/chipset.cb"
+
+config FSP_HEADER_PATH
+ string "Location of FSP headers"
+ default "src/vendorcode/intel/fsp/fsp2_0/graniterapids/ap"
+
+config MAX_CPUS
+ int
+ default 255
+
+config PCR_BASE_ADDRESS
+ hex
+ default 0xf7000000
+ help
+ This option allows you to select MMIO Base Address of sideband bus.
+
+config INTEL_PCH_PWRM_BASE_ADDRESS
+ hex
+ default 0xf6800000
+ help
+ PCH PWRM Base address.
+
+config DCACHE_RAM_BASE
+ hex
+ default 0xfe800000
+
+config DCACHE_RAM_SIZE
+ hex
+ default 0x1fff00
+ help
+ The size of the cache-as-ram region required during bootblock
+ and/or romstage. FSP-T reserves the upper 0x100 for
+ FspReservedBuffer.
+
+config DCACHE_BSP_STACK_SIZE
+ hex
+ default 0x60000
+ help
+ The amount of anticipated stack usage in CAR by bootblock and
+ other stages. It needs to include FSP-M stack requirement and
+ CB romstage stack requirement. The integration documentation
+ says this needs to be 256KiB.
+
+config FSP_M_RC_HEAP_SIZE
+ hex
+ default 0x142000
+ help
+ On xeon_sp/gnr FSP-M has two separate heap managers, one regular
+ whose size and base are controllable via the StackBase and
+ StackSize UPDs and a 'rc' heap manager that is statically
+ allocated at 0xfe800000 (the CAR base) and consumes about 0x142000
+ bytes of memory.
+
+config HEAP_SIZE
+ hex
+ default 0x80000
+
+config STACK_SIZE
+ hex
+ default 0x4000
+
+config FSP_TEMP_RAM_SIZE
+ hex
+ depends on FSP_USES_CB_STACK
+ default 0x58000
+ help
+ The amount of anticipated heap usage in CAR by FSP.
+ Refer to Platform FSP integration guide document to know
+ the exact FSP requirement for Heap setup. The FSP integration
+ documentation says this needs to be at least 128KiB, but practice
+ show this needs to be 256KiB or more.
+
+config IED_REGION_SIZE
+ hex
+ default 0x400000
+
+config CPU_BCLK_MHZ
+ int
+ default 100
+
+# DDR4
+config DIMM_SPD_SIZE
+ int
+ default 1024
+
+config MAX_ACPI_TABLE_SIZE_KB
+ int
+ default 224
+
+config SOC_INTEL_HAS_NCMEM
+ def_bool y
+
+config SOC_INTEL_MMAPVTD_ONLY_FOR_DPR
+ def_bool y
+
+config SOC_INTEL_HAS_CXL
+ def_bool n
+
+config INTEL_SPI_BASE_ADDRESS
+ hex
+ default 0xf6830000
+ help
+ SPI BAR0 Base address.
+
+endif
diff --git a/src/soc/intel/xeon_sp/gnr/Makefile.mk b/src/soc/intel/xeon_sp/gnr/Makefile.mk
new file mode 100644
index 0000000000..019684b629
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/Makefile.mk
@@ -0,0 +1,28 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+ifeq ($(CONFIG_SOC_INTEL_GRANITERAPIDS),y)
+
+subdirs-y += ../../../../cpu/intel/turbo
+subdirs-y += ../../../../cpu/x86/lapic
+subdirs-y += ../../../../cpu/x86/mtrr
+subdirs-y += ../../../../cpu/x86/smm
+subdirs-y += ../../../../cpu/x86/tsc
+subdirs-y += ../../../../cpu/intel/microcode
+
+romstage-y += romstage.c
+romstage-y += soc_util.c
+romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
+
+ramstage-y += chip.c
+ramstage-y += cpu.c
+ramstage-y += soc_util.c
+ramstage-y += ramstage.c
+ramstage-y += soc_acpi.c
+ramstage-y += ../chip_gen6.c
+
+CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/gnr/include
+CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/gnr
+
+CFLAGS_common += -fshort-wchar
+
+endif ## CONFIG_SOC_INTEL_GRANITERAPIDS
diff --git a/src/soc/intel/xeon_sp/gnr/acpi/gpe.asl b/src/soc/intel/xeon_sp/gnr/acpi/gpe.asl
new file mode 100644
index 0000000000..b61ffcf4fb
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/acpi/gpe.asl
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <soc/iomap.h>
+
+Scope (\_SB)
+{
+ Scope (\_GPE)
+ {
+ OperationRegion (PMIO, SystemIO, ACPI_BASE_ADDRESS, 0xFF)
+ Field (PMIO, ByteAcc, NoLock, Preserve) {
+ Offset(0x34), /* 0x34, SMI/SCI STS*/
+ , 9,
+ SGCS, 1, /* SWGPE STS BIT */
+
+ Offset(0x40), /* 0x40, SMI/SCI_EN*/
+ , 17,
+ SGPC, 1, /* SWGPE CTRL BIT */
+
+ Offset(0x6C), /* 0x6C, General Purpose Event 0 Status [127:96] */
+ , 2,
+ SGPS, 1, /* SWGPE STATUS */
+
+ Offset(0x7C), /* 0x7C, General Purpose Event 0 Enable [127:96] */
+ , 2,
+ SGPE, 1 /* SWGPE ENABLE */
+ }
+ Method (_L62, 0, NotSerialized)
+ {
+ DBGO("\\_GPE\\_L62\n")
+ SGPC = 0 // clear SWGPE control
+ SGPS = 1 // clear SWGPE Status
+ }
+ }
+}
diff --git a/src/soc/intel/xeon_sp/gnr/chip.c b/src/soc/intel/xeon_sp/gnr/chip.c
new file mode 100644
index 0000000000..23458944c7
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/chip.c
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <intelblocks/lpc_lib.h>
+#include <intelblocks/pmclib.h>
+#include <soc/pm.h>
+#include <soc/chip_common.h>
+#include <soc/ramstage.h>
+
+#include "chip.h"
+
+struct device_operations hpet_device_ops = {
+#if CONFIG(HAVE_ACPI_TABLES)
+ .write_acpi_tables = &acpi_write_hpet,
+#endif
+};
+
+struct device_operations cpu_bus_ops = {
+ .init = mp_cpu_bus_init,
+};
+
+struct pci_operations soc_pci_ops = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static void chip_enable_dev(struct device *dev)
+{
+ switch (dev->path.type) {
+ case DEVICE_PATH_GPIO:
+ block_gpio_enable(dev);
+ break;
+ default:
+ break;
+ }
+}
+
+static void chip_init(void *data)
+{
+ printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n");
+ fsp_silicon_init();
+
+ attach_iio_stacks();
+ pch_enable_ioapic();
+
+ pmc_gpe_init();
+ pmc_disable_all_gpe();
+ pmc_write_pm1_control(pmc_read_pm1_control() | SCI_EN);
+}
+
+struct chip_operations soc_intel_xeon_sp_gnr_ops = {
+ .name = "Intel GNR",
+ .enable_dev = chip_enable_dev,
+ .init = chip_init,
+};
+
+/* UPD parameters to be initialized before SiliconInit */
+void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
+{
+ mainboard_silicon_init_params(silupd);
+}
diff --git a/src/soc/intel/xeon_sp/gnr/chip.h b/src/soc/intel/xeon_sp/gnr/chip.h
new file mode 100644
index 0000000000..387b641e95
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/chip.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_CHIP_H_
+#define _SOC_CHIP_H_
+
+#include <intelblocks/cfg.h>
+#include <soc/acpi.h>
+#include <soc/gpio.h>
+#include <soc/irq.h>
+#include <stdint.h>
+
+struct soc_intel_xeon_sp_gnr_config {
+ /* Common struct containing soc config data required by common code */
+ struct soc_intel_common_config common_soc_config;
+
+ bool vtd_support;
+ uint8_t debug_print_level;
+ uint16_t serial_io_uart_debug_io_base;
+
+ /* Generic IO decode ranges */
+ uint32_t gen1_dec;
+ uint32_t gen2_dec;
+ uint32_t gen3_dec;
+ uint32_t gen4_dec;
+
+ uint32_t tcc_offset;
+ enum acpi_cstate_mode cstate_states;
+};
+
+typedef struct soc_intel_xeon_sp_gnr_config config_t;
+
+#endif
diff --git a/src/soc/intel/xeon_sp/gnr/chipset.cb b/src/soc/intel/xeon_sp/gnr/chipset.cb
new file mode 100644
index 0000000000..ef33eac9d2
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/chipset.cb
@@ -0,0 +1,21 @@
+## SPDX-License-Identifier: GPL-2.0-or-later
+
+chip soc/intel/xeon_sp/gnr
+
+ # configure VT-d
+ register "vtd_support" = "1"
+
+ # configure BIOS lockdown
+ register "common_soc_config" = "{
+ .chipset_lockdown = CHIPSET_LOCKDOWN_FSP,
+ }"
+
+ # configure devices
+ device cpu_cluster 0 on ops cpu_bus_ops end
+
+ device domain 0 on
+ device pci 00.0 mandatory end # MMAP/VT-d
+ device gpio 0 alias ibl_gpio_communities on end # GPIO
+ device mmio 0xfed00000 on ops hpet_device_ops end # HPET
+ end
+end
diff --git a/src/soc/intel/xeon_sp/gnr/cpu.c b/src/soc/intel/xeon_sp/gnr/cpu.c
new file mode 100644
index 0000000000..43120b33cc
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/cpu.c
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <cpu/intel/common/common.h>
+#include <cpu/intel/microcode.h>
+#include <cpu/x86/mp.h>
+#include <cpu/x86/mtrr.h>
+#include <intelblocks/cpulib.h>
+#include <intelblocks/mp_init.h>
+#include <soc/cpu.h>
+#include <soc/soc_util.h>
+#include <soc/util.h>
+
+#include "chip.h"
+
+static const void *microcode_patch;
+
+static const config_t *chip_config = NULL;
+
+bool cpu_soc_is_in_untrusted_mode(void)
+{
+ // FIXME: not implemented yet
+ return false;
+}
+
+void get_microcode_info(const void **microcode, int *parallel)
+{
+ *microcode = intel_microcode_find();
+ *parallel = 0;
+}
+
+static void each_cpu_init(struct device *cpu)
+{
+ printk(BIOS_SPEW, "%s dev: %s, cpu: %lu, apic_id: 0x%x\n",
+ __func__, dev_path(cpu), cpu_index(), cpu->path.apic.apic_id);
+
+ /* Enable VMX */
+ set_vmx_and_lock();
+}
+
+static struct device_operations cpu_dev_ops = {
+ .init = each_cpu_init,
+};
+
+static const struct cpu_device_id cpu_table[] = {
+ { X86_VENDOR_INTEL, CPUID_GRANITERAPIDS, CPUID_ALL_STEPPINGS_MASK },
+ { X86_VENDOR_INTEL, CPUID_SIERRAFOREST, CPUID_ALL_STEPPINGS_MASK },
+ CPU_TABLE_END
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+ .ops = &cpu_dev_ops,
+ .id_table = cpu_table,
+};
+
+/*
+ * Do essential initialization tasks before APs can be fired up
+ */
+static void pre_mp_init(void)
+{
+ x86_setup_mtrrs_with_detect();
+ x86_mtrr_check();
+}
+
+static int get_thread_count(void)
+{
+ unsigned int num_phys = 0, num_virts = 0;
+
+ /*
+ * This call calculates the thread count which is corresponding to num_virts
+ * (logical cores), while num_phys is corresponding to physical cores (in SMT
+ * system, one physical core has multiple threads, a.k.a. logical cores).
+ * Hence num_phys is not actually used.
+ */
+ cpu_read_topology(&num_phys, &num_virts);
+ printk(BIOS_SPEW, "Detected %u cores and %u threads\n", num_phys, num_virts);
+ return num_virts * soc_get_num_cpus();
+}
+
+static void post_mp_init(void)
+{
+ if (CONFIG(HAVE_SMI_HANDLER))
+ global_smi_enable();
+}
+
+static const struct mp_ops mp_ops = {
+ .pre_mp_init = pre_mp_init,
+ .get_cpu_count = get_thread_count,
+ .get_microcode_info = get_microcode_info,
+ .post_mp_init = post_mp_init,
+};
+
+void mp_init_cpus(struct bus *bus)
+{
+ /*
+ * chip_config is used in CPU device callback. Other than CPU 0,
+ * rest of the CPU devices do not have chip_info updated.
+ */
+ chip_config = bus->dev->chip_info;
+
+ microcode_patch = intel_microcode_find();
+ intel_microcode_load_unlocked(microcode_patch);
+
+ enum cb_err ret = mp_init_with_smm(bus, &mp_ops);
+ if (ret != CB_SUCCESS)
+ printk(BIOS_ERR, "MP initialization failure %d.\n", ret);
+}
diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/cpu.h b/src/soc/intel/xeon_sp/gnr/include/soc/cpu.h
new file mode 100644
index 0000000000..76d33195f8
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/include/soc/cpu.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_CPU_H
+#define _SOC_CPU_H
+
+#define CPUID_GRANITERAPIDS 0xA06D0
+#define CPUID_SIERRAFOREST 0xA06F0
+
+#endif
diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h
new file mode 100644
index 0000000000..e2c63dbd21
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* TEMPORARY PLACE HOLDER! DO NOT USE! */
+/* FORKED FROM src/soc/intel/xeon_sp/spr/include/soc/pci_devs.h */
+
+#ifndef _SOC_PCI_DEVS_H_
+#define _SOC_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+#include <device/pci_type.h>
+#include <soc/pch_pci_devs.h>
+#include <types.h>
+
+#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_##slot, 0)
+
+#if !defined(__SIMPLE_DEVICE__)
+#include <device/device.h>
+#define _SA_DEV(slot) pcidev_path_on_root_debug(_SA_DEVFN(slot), __func__)
+#else
+#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_##slot, 0)
+#endif
+
+#define UNCORE_BUS_0 0
+#define UNCORE_BUS_1 1
+
+/* UBOX Registers [U(1), D:0, F:1] */
+#define SMM_FEATURE_CONTROL 0x8c
+#define SMM_CODE_CHK_EN BIT(2)
+#define SMM_FEATURE_CONTROL_LOCK BIT(0)
+#define UBOX_DFX_DEVID 0x3251
+
+/* CHA registers [B:31, D:29, F:0/F:1]
+ * SAD is the previous xeon_sp register name. Keep defines for shared code.
+ */
+#define CHA_DEV 29
+
+#define SAD_ALL_DEV CHA_DEV
+#define SAD_ALL_FUNC 0
+#define SAD_ALL_PAM0123_CSR 0x80
+#define SAD_ALL_PAM456_CSR 0x84
+#define SAD_ALL_DEVID 0x344f
+
+#if !defined(__SIMPLE_DEVICE__)
+#define _PCU_DEV(bus, func) pcidev_path_on_bus(bus, PCI_DEVFN(PCU_DEV, func))
+#else
+#define _PCU_DEV(bus, func) PCI_DEV(bus, PCU_DEV, func)
+#endif
+
+/* PCU [B:31, D:30, F:0->F:6] */
+#define PCU_IIO_STACK UNCORE_BUS_1
+#define PCU_DEV 30
+
+#define PCU_CR0_FUN 0
+#define PCU_CR0_DEVID 0x3258
+#define PCU_DEV_CR0(bus) _PCU_DEV(bus, PCU_CR0_FUN)
+#define PCU_CR0_PLATFORM_INFO 0xa8
+#define PCU_CR0_TURBO_ACTIVATION_RATIO 0xb0
+#define TURBO_ACTIVATION_RATIO_LOCK BIT(31)
+#define PCU_CR0_P_STATE_LIMITS 0xd8
+#define P_STATE_LIMITS_LOCK BIT(31)
+#define PCU_CR0_PACKAGE_RAPL_LIMIT_LWR 0xe8
+#define PCU_CR0_PACKAGE_RAPL_LIMIT_UPR (PCU_CR0_PACKAGE_RAPL_LIMIT_LWR + 4)
+#define PKG_PWR_LIM_LOCK_UPR BIT(31)
+#define PCU_CR0_PMAX 0xf0
+#define PMAX_LOCK BIT(31)
+#define PCU_CR0_VR_CURRENT_CONFIG_CFG 0xf8
+#define VR_CURRENT_CONFIG_LOCK BIT(31)
+
+#define PCU_CR1_FUN 1
+#define PCU_CR1_DEVID 0x3259
+#define PCU_DEV_CR1(bus) _PCU_DEV(bus, PCU_CR1_FUN)
+#define PCU_CR1_BIOS_MB_DATA_REG 0x8c
+
+#define PCU_CR1_BIOS_MB_INTERFACE_REG 0x90
+#define BIOS_MB_RUN_BUSY_MASK BIT(31)
+#define BIOS_MB_CMD_MASK 0xff
+#define BIOS_CMD_READ_PCU_MISC_CFG 0x5
+#define BIOS_CMD_WRITE_PCU_MISC_CFG 0x6
+#define BIOS_ERR_INVALID_CMD 0x01
+
+#define PCU_CR1_BIOS_RESET_CPL_REG 0x94
+#define RST_CPL1_MASK BIT(1)
+#define RST_CPL2_MASK BIT(2)
+#define RST_CPL3_MASK BIT(3)
+#define RST_CPL4_MASK BIT(4)
+#define PCODE_INIT_DONE1_MASK BIT(9)
+#define PCODE_INIT_DONE2_MASK BIT(10)
+#define PCODE_INIT_DONE3_MASK BIT(11)
+#define PCODE_INIT_DONE4_MASK BIT(12)
+
+#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xbc
+#define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK BIT(31)
+
+#define PCU_CR2_FUN 2
+#define PCU_CR2_DEVID 0x325a
+#define PCU_DEV_CR2(bus) _PCU_DEV(bus, PCU_CR2_FUN)
+#define PCU_CR2_DRAM_POWER_INFO_LWR 0xa8
+#define PCU_CR2_DRAM_POWER_INFO_UPR (PCU_CR2_DRAM_POWER_INFO_LWR + 4)
+#define DRAM_POWER_INFO_LOCK_UPR BIT(31)
+
+#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR 0xf0
+#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR (PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR + 4)
+#define PP_PWR_LIM_LOCK_UPR BIT(31)
+
+#define PCU_CR3_FUN 3
+#define PCU_CR3_DEVID 0x325b
+#define PCU_CR3_CAPID4 0x94
+#define ERR_SPOOFING_DIS 1
+#define PCU_DEV_CR3(bus) _PCU_DEV(bus, PCU_CR3_FUN)
+#define PCU_CR3_CONFIG_TDP_CONTROL 0xd8
+#define TDP_LOCK BIT(31)
+#define PCU_CR3_FLEX_RATIO 0xa0
+#define OC_LOCK BIT(20)
+
+#define PCU_CR4_FUN 4
+#define PCU_CR4_DEVID 0x325c
+#define PCU_VIRAL_CONTROL 0x84
+#define PCU_FW_ERR_EN (1 << 10)
+#define PCU_UC_ERR_EN (1 << 9)
+#define PCU_HW_ERR_EN (1 << 8)
+#define PCU_EMCA_MODE (1 << 2)
+
+#define PCU_CR6_FUN 6
+#define PCU_CR6_DEVID 0x325e
+#define PCU_DEV_CR6(bus) _PCU_DEV(bus, PCU_CR6_FUN)
+#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR 0xa8
+#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_UPR (PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR + 4)
+#define PLT_PWR_LIM_LOCK_UPR BIT(31)
+#define PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR 0xb0
+#define PCU_CR6_PLATFORM_POWER_INFO_CFG_UPR (PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR + 4)
+#define PLT_PWR_INFO_LOCK_UPR BIT(31)
+
+/* Memory Map/VTD Device Functions
+ * These are available in each IIO stack
+ */
+#define MMAP_VTD_DEV 0x0
+#define MMAP_VTD_FUNC 0x0
+
+#define VTD_TOLM_CSR 0xd0
+#define VTD_TSEG_BASE_CSR 0xa8
+#define VTD_TSEG_LIMIT_CSR 0xac
+#define VTD_EXT_CAP_LOW 0x10
+#define VTD_MMCFG_BASE_CSR 0x90
+#define VTD_MMCFG_LIMIT_CSR 0x98
+#define VTD_TOHM_CSR 0xc8
+#define VTD_MMIOL_CSR 0xd8
+#define VTD_NCMEM_BASE_CSR 0xe0
+#define VTD_NCMEM_LIMIT_CSR 0xe8
+#define VTD_BAR_CSR 0x180
+#define VTD_LTDPR 0x290
+
+#define VMD_DEV_NUM 0x00
+#define VMD_FUNC_NUM 0x05
+
+#define MMAP_VTD_CFG_REG_DEVID 0x09a2
+#define MMAP_VTD_STACK_CFG_REG_DEVID 0x09a2
+#define VTD_DEV_NUM 0x0
+#define VTD_FUNC_NUM 0x0
+
+#if !defined(__SIMPLE_DEVICE__)
+#define VTD_DEV(bus) pcidev_path_on_bus((bus), PCI_DEVFN(VTD_DEV_NUM, VTD_FUNC_NUM))
+#else
+#define VTD_DEV(bus) PCI_DEV((bus), VTD_DEV_NUM, VTD_FUNC_NUM)
+#endif
+
+/* Root port Registers */
+
+/* IEH */
+#define IEH_EXT_CAP_ID 0x7 /* At 0x160 */
+#define GSYSEVTCTL 0x104 /* Offset from IEH_EXT_CAP_ID */
+#define CE_ERR_UNMSK 1
+#define NON_FATAL_UNMSK (1 << 1)
+#define FATAL_UNMSK (1 << 2)
+#define GSYSEVTMAP 0x108 /* Offset from IEH_EXT_CAP_ID */
+#define CE_SMI 1
+#define NF_SMI (1 << 2)
+#define FA_SMI (1 << 4)
+
+
+#define DMIRCBAR 0x50
+#define DMI3_DEVID 0x2020
+#define PCIE_ROOTCTL 0x5c
+#define ERRINJCON 0x198
+
+/* IIO DFX Global D7F7 registers */
+#define IIO_DFX_TSWCTL0 0x30c
+#define IIO_DFX_LCK_CTL 0x504
+
+/* XHCI register */
+#define SYS_BUS_CFG2 0x44
+
+/* MSM registers */
+#define MSM_BUS 0xF2
+#define MSM_DEV 3
+#define MSM_FUN 0
+#define MSM_FUN_PMON 1
+#define CRASHLOG_CTL 0x1B8
+#define BIOS_CRASHLOG_CTL 0x158
+#define CRASHLOG_CTL_DIS BIT(2)
+
+#endif /* _SOC_PCI_DEVS_H_ */
diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h b/src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h
new file mode 100644
index 0000000000..1cd7ab4739
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* TEMPORARY PLACE HOLDER! DO NOT USE! */
+/* FORMED FROM src/soc/intel/xeon_sp/spr/include/soc/soc_msr.h */
+
+#ifndef _SOC_MSR_SPR_H_
+#define _SOC_MSR_SPR_H_
+
+#define MSR_CPU_BUSNO 0x128
+#define BUSNO_VALID (1 << 31) /* used as msr.hi */
+
+/* IA32_ERR_CTRL */
+#define CMCI_DISABLE (1 << 4)
+
+/* MSR_PKG_CST_CONFIG_CONTROL */
+#define PKG_CSTATE_NO_LIMIT (0x8 << PKG_CSTATE_LIMIT_SHIFT)
+
+/* MSR_POWER_CTL */
+#define RESERVED1_SHIFT 2
+#define PWR_PERF_PLTFRM_OVR_SHIFT 18
+#define PWR_PERF_PLTFRM_OVR (1 << PWR_PERF_PLTFRM_OVR_SHIFT)
+#define EE_TURBO_DISABLE_SHIFT 19
+#define EE_TURBO_DISABLE (1 << EE_TURBO_DISABLE_SHIFT)
+#define RTH_DISABLE_SHIFT 20
+#define RTH_DISABLE (1 << RTH_DISABLE_SHIFT)
+#define PROCHOT_OUTPUT_DISABLE_SHIFT 21
+#define PROCHOT_OUTPUT_DISABLE (1 << PROCHOT_OUTPUT_DISABLE_SHIFT)
+#define PROCHOT_RESPONSE_SHIFT 22
+#define PROCHOT_RESPONSE (1 << PROCHOT_RESPONSE_SHIFT)
+#define PROCHOT_LOCK_SHIFT 23
+#define PROCHOT_LOCK (1 << PROCHOT_LOCK_SHIFT)
+#define VR_THERM_ALERT_DISABLE_SHIFT 24
+#define VR_THERM_ALERT_DISABLE (1 << VR_THERM_ALERT_DISABLE_SHIFT)
+#define DISABLE_RING_EE_SHIFT 25
+#define DISABLE_RING_EE (1 << DISABLE_RING_EE_SHIFT)
+#define RESERVED2_SHIFT 26
+#define DISABLE_AUTONOMOUS_SHIFT 28
+#define DISABLE_AUTONOMOUS (1 << DISABLE_AUTONOMOUS_SHIFT)
+#define RESERVED3_SHIFT 29
+#define CSTATE_PREWAKE_DISABLE_SHIFT 30
+#define CSTATE_PREWAKE_DISABLE (1 << CSTATE_PREWAKE_DISABLE_SHIFT)
+
+/* SPR has banks 0-20 and 29-31 */
+#define IA32_MC20_CTL2 0x294
+#define IA32_MC29_CTL2 0x29D
+#define IA32_MC30_CTL2 0x29E
+#define IA32_MC31_CTL2 0x29F
+
+#define MSR_PERRINJ_AT_IP 0x107
+#define MSR_PERRINJ_AT_IP_ENABLE BIT(31)
+
+#define MSR_BIOS_DONE 0x151
+#define XEON_SP_ENABLE_IA_UNTRUSTED BIT(0)
+
+#define MSR_FLEX_RATIO 0x194
+#define MSR_FLEX_RATIO_OC_LOCK BIT(20)
+
+/* B1:D30:F0 offset 0xe8 on previous generations */
+#define PACKAGE_RAPL_LIMIT 0x610
+
+#define MSR_DRAM_PLANE_POWER_LIMIT 0x618
+#define MSR_HI_PP_PWR_LIM_LOCK BIT(31) /* used as msr.hi */
+
+#endif /* _SOC_MSR_SPR_H_ */
diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h b/src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h
new file mode 100644
index 0000000000..1cfb10553b
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_UTIL_H_
+#define _SOC_UTIL_H_
+
+#include <device/device.h>
+#include <device/pci.h>
+
+#include <fsp/util.h>
+#include <CxlNodeHob.h>
+#include <FspAcpiHobs.h>
+#include <IioUniversalDataHob.h>
+#include <MemoryMapDataHob.h>
+
+#define xSTACK_RES UDS_STACK_RES
+#define xIIO_RESOURCE_INSTANCE UDS_SOCKET_RES
+
+#define FSP_HOB_IIO_UNIVERSAL_DATA_GUID { \
+ 0xa1, 0x96, 0xf3, 0x7f, 0x7d, 0xee, 0x1e, 0x43, \
+ 0xba, 0x53, 0x8f, 0xCa, 0x12, 0x7c, 0x44, 0xc0 \
+}
+
+const struct SystemMemoryMapHob *get_system_memory_map(void);
+const struct SystemMemoryMapElement *get_system_memory_map_elment(uint8_t *num);
+
+const CXL_NODE_SOCKET *get_cxl_node(void);
+uint8_t get_cxl_node_count(void);
+
+const char *pciroot_res_to_domain_type(const UDS_STACK_RES *sr, const UDS_PCIROOT_RES *rr);
+
+#endif /* _SOC_UTIL_H_ */
diff --git a/src/soc/intel/xeon_sp/gnr/ramstage.c b/src/soc/intel/xeon_sp/gnr/ramstage.c
new file mode 100644
index 0000000000..7a0453a67a
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/ramstage.c
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <fsp/api.h>
+#include <soc/ramstage.h>
+
+unsigned int smbios_cpu_get_voltage(void)
+{
+ return 16; /* Per SMBIOS spec, voltage times 10 */
+}
diff --git a/src/soc/intel/xeon_sp/gnr/romstage.c b/src/soc/intel/xeon_sp/gnr/romstage.c
new file mode 100644
index 0000000000..95b2e15a5d
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/romstage.c
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <soc/romstage.h>
+
+static uint8_t get_mmcfg_base_upd_index(const uint64_t base_addr)
+{
+ switch (base_addr) {
+ case 1ULL * GiB: // 1G
+ return 0;
+ case 1ULL * GiB + 512ULL * MiB: // 1.5G
+ return 0x1;
+ case 1ULL * GiB + 768ULL * MiB: // 1.75G
+ return 0x2;
+ case 2ULL * GiB: // 2G
+ return 0x3;
+ case 2ULL * GiB + 256ULL * MiB: // 2.25G
+ return 0x4;
+ case 3ULL * GiB: // 3G
+ return 0x5;
+ default: // Auto
+ return 0x6;
+ }
+}
+
+static uint8_t get_mmcfg_size_upd_index(const uint64_t size)
+{
+ switch (size) {
+ case 64ULL * MiB: // 64M
+ return 0;
+ case 128ULL * MiB: // 128M
+ return 0x1;
+ case 256ULL * MiB: // 256M
+ return 0x2;
+ case 512ULL * MiB: // 512M
+ return 0x3;
+ case 1ULL * GiB: // 1G
+ return 0x4;
+ case 2ULL * GiB: // 2G
+ return 0x5;
+ default: // Auto
+ return 0x6;
+ }
+}
+
+void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
+{
+ FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
+ m_cfg->mmCfgBase = get_mmcfg_base_upd_index(CONFIG_ECAM_MMCONF_BASE_ADDRESS);
+ m_cfg->mmCfgSize = get_mmcfg_size_upd_index(CONFIG_ECAM_MMCONF_LENGTH);
+
+ /* Board level settings */
+ mainboard_memory_init_params(mupd);
+}
diff --git a/src/soc/intel/xeon_sp/gnr/soc_acpi.c b/src/soc/intel/xeon_sp/gnr/soc_acpi.c
new file mode 100644
index 0000000000..6f1df7c386
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/soc_acpi.c
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <assert.h>
+#include <intelblocks/acpi.h>
+#include <intelblocks/pcr.h>
+#include <intelblocks/itss.h>
+#include <soc/acpi.h>
+#include <soc/soc_util.h>
+#include <soc/util.h>
+#include <soc/itss.h>
+#include <soc/pcr_ids.h>
+
+int soc_madt_sci_irq_polarity(int sci)
+{
+ int reg = sci / IRQS_PER_IPC;
+ int offset = sci % IRQS_PER_IPC;
+ uint32_t val = pcr_read32(PID_ITSS, PCR_ITSS_IPC0_CONF + reg * sizeof(uint32_t));
+
+ return (val & (1 << offset)) ? MP_IRQ_POLARITY_LOW : MP_IRQ_POLARITY_HIGH;
+}
+
+uint32_t soc_read_sci_irq_select(void)
+{
+ const uint16_t pmbase = ACPI_BASE_ADDRESS;
+ return inl(pmbase + PMC_ACPI_CNT);
+}
+
+void soc_fill_fadt(acpi_fadt_t *fadt)
+{
+ const uint16_t pmbase = ACPI_BASE_ADDRESS;
+
+ fadt->pm_tmr_blk = pmbase + PM1_TMR;
+ fadt->pm_tmr_len = 4;
+ fadt->flags &= ~(ACPI_FADT_SEALED_CASE | ACPI_FADT_S4_RTC_WAKE);
+ fadt->preferred_pm_profile = PM_ENTERPRISE_SERVER;
+}
+
+void soc_power_states_generation(int core, int cores_per_package)
+{
+ generate_p_state_entries(core, cores_per_package);
+}
diff --git a/src/soc/intel/xeon_sp/gnr/soc_util.c b/src/soc/intel/xeon_sp/gnr/soc_util.c
new file mode 100644
index 0000000000..a65e5fcc52
--- /dev/null
+++ b/src/soc/intel/xeon_sp/gnr/soc_util.c
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <assert.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <fsp/util.h>
+#include <soc/util.h>
+#include <soc/acpi.h>
+#include <soc/chip_common.h>
+#include <soc/cpu.h>
+#include <soc/pci_devs.h>
+#include <soc/soc_util.h>
+#include <stdlib.h>
+#include <string.h>
+#include <MemoryMapDataHob.h>
+
+const char *pciroot_res_to_domain_type(const UDS_STACK_RES *sr, const UDS_PCIROOT_RES *pr)
+{
+ int index = 0;
+ int instance = -1;
+
+ for (; index < sr->PciRootBridgeNum; index++) {
+ if (sr->PciRoot[index].UidType == pr->UidType)
+ instance++;
+ if (sr->PciRoot[index].BusBase == pr->BusBase)
+ break;
+ }
+
+ if (index == sr->PciRootBridgeNum)
+ return NULL;
+
+ switch (pr->UidType) {
+ case PC_UID:
+ return DOMAIN_TYPE_PCIE;
+ case DINO_UID:
+ return DOMAIN_TYPE_DINO;
+ case CPM0_UID:
+ return DOMAIN_TYPE_CPM0;
+ case HQM0_UID:
+ return DOMAIN_TYPE_HQM0;
+ case UB_UID:
+ return (instance == 0) ? DOMAIN_TYPE_UBX0 : DOMAIN_TYPE_UBX1;
+ default:
+ return NULL;
+ }
+}
+
+static bool is_domain_type_supported_on_stack(const xSTACK_RES *sr, const char *dt)
+{
+ for (unsigned int index = 0; index < sr->PciRootBridgeNum; index++)
+ if (!strcmp(dt, pciroot_res_to_domain_type(sr, &sr->PciRoot[index])))
+ return true;
+
+ return false;
+}
+
+bool is_pcie_iio_stack_res(const xSTACK_RES *res)
+{
+ return is_domain_type_supported_on_stack(res, DOMAIN_TYPE_PCIE);
+}
+
+bool is_ioat_iio_stack_res(const xSTACK_RES *res)
+{
+ return (is_domain_type_supported_on_stack(res, DOMAIN_TYPE_DINO) ||
+ is_domain_type_supported_on_stack(res, DOMAIN_TYPE_CPM0) ||
+ is_domain_type_supported_on_stack(res, DOMAIN_TYPE_HQM0));
+
+}
+
+bool is_ubox_stack_res(const xSTACK_RES *res)
+{
+ return (is_domain_type_supported_on_stack(res, DOMAIN_TYPE_UBX0) ||
+ is_domain_type_supported_on_stack(res, DOMAIN_TYPE_UBX1));
+}
+
+bool is_iio_cxl_stack_res(const xSTACK_RES *res)
+{
+ return false;
+}
+
+const struct SystemMemoryMapHob *get_system_memory_map(void)
+{
+ size_t hob_size;
+ const EFI_GUID mem_hob_guid = MEMORY_MAP_HOB_GUID;
+ const struct SystemMemoryMapHob **memmap_addr;
+
+ memmap_addr = (const struct SystemMemoryMapHob **)
+ fsp_find_extension_hob_by_guid((uint8_t *)&mem_hob_guid, &hob_size);
+ /* hob_size is the size of the 8-byte address not the hob data */
+ assert(memmap_addr != NULL && hob_size != 0);
+ /* assert the pointer to the hob is not NULL */
+ assert(*memmap_addr != NULL);
+
+ return *memmap_addr;
+}
+
+const struct SystemMemoryMapElement *get_system_memory_map_elment(uint8_t *num)
+{
+ const struct SystemMemoryMapHob *hob = get_system_memory_map();
+ if (!hob)
+ return NULL;
+
+ *num = hob->numberEntries;
+ return hob->Element;
+}
+
+const CXL_NODE_SOCKET *get_cxl_node(void)
+{
+ size_t hob_size;
+ static const CXL_NODE_SOCKET *hob;
+ const EFI_GUID fsp_hob_cxl_node_socket_guid = CXL_NODE_HOB_GUID;
+
+ if (hob != NULL)
+ return hob;
+
+ hob = fsp_find_extension_hob_by_guid((uint8_t *)&fsp_hob_cxl_node_socket_guid, &hob_size);
+ if (hob == NULL || hob_size == 0) {
+ printk(BIOS_DEBUG, "CXL_NODE_HOB_GUID not found: CXL may not be installed\n");
+ return NULL;
+ }
+ return hob;
+}
+
+uint8_t get_cxl_node_count(void)
+{
+ const CXL_NODE_SOCKET *hob = get_cxl_node();
+ uint8_t count = 0;
+
+ if (hob == NULL)
+ return 0;
+ for (unsigned int skt_id = 0 ; skt_id < MAX_SOCKET; skt_id++)
+ count += hob[skt_id].CxlNodeCount;
+
+ return count;
+}
+
+bool is_memtype_reserved(uint16_t mem_type)
+{
+ return false;
+}
+
+bool is_memtype_non_volatile(uint16_t mem_type)
+{
+ return false;
+}
+
+bool is_memtype_processor_attached(uint16_t mem_type)
+{
+ return true;
+}