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>
This commit is contained in:
Jonathan Zhang 2023-01-30 12:11:52 -08:00 committed by Lean Sheng Tan
parent a5bd580b5f
commit 907b6f54ef
2 changed files with 117 additions and 3 deletions

View File

@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* This header file defines data structures and operations related
* to NUMA proximity domains.
*/
#ifndef NUMA_H
#define NUMA_H
#include <types.h>
enum proximity_domain_type {
PD_TYPE_PROCESSOR,
/*
* The Generic Initiator concept is used in ACPI spec. A typical
* Generic Initiator domain is a CXL memory device.
*/
PD_TYPE_GENERIC_INITIATOR,
};
/*
* This proximity domain structure records all data related to
* a proximity doamin needed for following purpose:
* a. Device resource allocation. IIO stack involving CXL device
* needs to have different resource allocation method.
* b. e820 table setup. For example, CXL memory region may need to
* be set as soft reserved, since it is specific purpose memory.
* c. ACPI NUMA tables (SRAT, SLIT, HMAT).
*/
struct proximity_domain {
enum proximity_domain_type pd_type;
/*
* For processor domain, this holds the socket #.
* For generic initiator domain, this indicates to which socket the
* device is attached to. CXL 2.0 allows interleaving within and between
* sockets, so we need a bitmap.
*/
uint8_t socket_bitmap;
/* Relative distances (memory latency) from all domains */
uint8_t *distances;
/*
* Below fields are set to 0 for processor domains.
*/
uint32_t device_handle; /* This holds PCIe device segment, BDF info */
uint32_t base; /* Memory region base address in the unit of 64MB */
uint32_t size; /* Memory region size in the unit of 64MB */
};
struct proximity_domains {
uint8_t num_pds;
struct proximity_domain *pds;
};
extern struct proximity_domains pds;
void dump_pds(void);
enum cb_err fill_pds(void);
/*
* Return the total size of memory regions in generic initiator affinity
* domains. The size is in unit of 64MB.
*/
uint32_t get_generic_initiator_mem_size(void);
#endif /* NUMA_H */

View File

@ -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 @@ static void mc_add_dram_resources(struct device *dev, int *res_count)
mc_values[TOLM_REG]);
LOG_RESOURCE("mmio_tolm", 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 @@ static void mmapvtd_read_resources(struct device *dev)
{
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);