soc/intel/xeon_sp/spr: Add header files and romstage code

Several FSP HOBs processing codes are similar to Intel Cooperlake-SP
codes in soc/intel/xeon_sp/cpx.
Register datasheet please reference Sapphire Rapids EDS Vol2 Doc#612246
and Emmitsburg PCH EDS Doc#606161.

Change-Id: Ia022534e5206dbeec946d3e5f3c66bcb5628748f
Signed-off-by: Jonathan Zhang <jonzhang@meta.com>
Signed-off-by: Johnny Lin <johnny_lin@wiwynn.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/72442
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-25 11:33:16 -08:00 committed by Lean Sheng Tan
parent ecb4a24eaa
commit 15fc45982b
11 changed files with 1365 additions and 0 deletions

View File

@ -11,6 +11,12 @@
#define CPUID_SKYLAKE_SP_A0_A1 0x506f0
#define CPUID_SKYLAKE_SP_B0 0x506f1
#define CPUID_SKYLAKE_SP_4 0x50654
#define CPUID_SAPPHIRERAPIDS_SP_D 0x0806f3
#define CPUID_SAPPHIRERAPIDS_SP_E0 0x0806f4
#define CPUID_SAPPHIRERAPIDS_SP_E2 0x0806f5
#define CPUID_SAPPHIRERAPIDS_SP_E3 0x0806f6
#define CPUID_SAPPHIRERAPIDS_SP_E4 0x0806f7
#define CPUID_SAPPHIRERAPIDS_SP_Ex 0x0806f8
#define CPUID_SKYLAKE_C0 0x406e2
#define CPUID_SKYLAKE_D0 0x406e3
#define CPUID_SKYLAKE_HQ0 0x506e1

View File

@ -0,0 +1,93 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <soc/ddr.h>
unsigned int get_ddr_millivolt(unsigned int ddr_voltage)
{
switch (ddr_voltage) {
case SPD_VDD_DDR4:
return 1200;
case SPD_VDD_DDR5:
return 1100;
default:
return 0;
}
}
unsigned int get_max_memory_speed(unsigned int commonTck)
{
if (commonTck <= DDR_8400_TCK_MIN)
return 8400;
else if (commonTck <= DDR_7600_TCK_MIN)
return 7600;
else if (commonTck <= DDR_7200_TCK_MIN)
return 7200;
else if (commonTck <= DDR_6800_TCK_MIN)
return 6800;
else if (commonTck <= DDR_6400_TCK_MIN)
return 6400;
else if (commonTck <= DDR_6000_TCK_MIN)
return 6000;
else if (commonTck <= DDR_5600_TCK_MIN)
return 5600;
else if (commonTck <= DDR_5200_TCK_MIN)
return 5200;
else if (commonTck <= DDR_4800_TCK_MIN)
return 4800;
else if (commonTck <= DDR_4400_TCK_MIN)
return 4400;
else if (commonTck <= DDR_4266_TCK_MIN)
return 4266;
else if (commonTck <= DDR_4200_TCK_MIN)
return 4200;
else if (commonTck <= DDR_4000_TCK_MIN)
return 4000;
else if (commonTck <= DDR_3800_TCK_MIN)
return 3800;
else if (commonTck <= DDR_3733_TCK_MIN)
return 3733;
else if (commonTck <= DDR_3600_TCK_MIN)
return 3600;
else if (commonTck <= DDR_3466_TCK_MIN)
return 3466;
else if (commonTck <= DDR_3400_TCK_MIN)
return 3400;
else if (commonTck <= DDR_3200_TCK_MIN)
return 3200;
else if (commonTck <= DDR_3000_TCK_MIN)
return 3000;
else if (commonTck <= DDR_2933_TCK_MIN)
return 2933;
else if (commonTck <= DDR_2800_TCK_MIN)
return 2800;
else if (commonTck <= DDR_2666_TCK_MIN)
return 2666;
else if (commonTck <= DDR_2600_TCK_MIN)
return 2600;
else if (commonTck <= DDR_2400_TCK_MIN)
return 2400;
else if (commonTck <= DDR_2200_TCK_MIN)
return 2200;
else if (commonTck <= DDR_2133_TCK_MIN)
return 2133;
else if (commonTck <= DDR_2000_TCK_MIN)
return 2000;
else if (commonTck <= DDR_1866_TCK_MIN)
return 1866;
else if (commonTck <= DDR_1800_TCK_MIN)
return 1800;
else if (commonTck <= DDR_1600_TCK_MIN)
return 1600;
else if (commonTck <= DDR_1400_TCK_MIN)
return 1400;
else if (commonTck <= DDR_1333_TCK_MIN)
return 1333;
else if (commonTck <= DDR_1200_TCK_MIN)
return 1200;
else if (commonTck <= DDR_1066_TCK_MIN)
return 1066;
else if (commonTck <= DDR_1000_TCK_MIN)
return 1000;
else
return 800;
}

View File

@ -0,0 +1,244 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <fsp/util.h>
#include <hob_cxlnode.h>
#include <hob_iiouds.h>
#include <hob_memmap.h>
#include <lib.h>
#include <soc/soc_util.h>
static const uint8_t fsp_hob_iio_uds_guid[16] = FSP_HOB_IIO_UNIVERSAL_DATA_GUID;
static const uint8_t fsp_hob_memmap_guid[16] = FSP_SYSTEM_MEMORYMAP_HOB_GUID;
static const uint8_t fsp_hob_cxlnode_guid[16] = FSP_HOB_CXLNODE_GUID;
struct guid_name_map {
const void *guid;
const char *name;
};
static const struct guid_name_map guid_names[] = {
{fsp_hob_iio_uds_guid, "FSP_HOB_IIO_UNIVERSAL_DATA_GUID"},
{fsp_hob_memmap_guid, "FSP_SYSTEM_MEMORYMAP_HOB_GUID"},
{fsp_hob_cxlnode_guid, "FSP_HOB_CXLNODE_GUID"},
};
const char *soc_get_guid_name(const uint8_t *guid)
{
size_t index;
/* Compare the GUID values in this module */
for (index = 0; index < ARRAY_SIZE(guid_names); index++)
if (fsp_guid_compare(guid, guid_names[index].guid))
return guid_names[index].name;
return NULL;
}
void soc_display_memmap_hob(const struct SystemMemoryMapHob **hob_addr)
{
struct SystemMemoryMapHob *hob = (struct SystemMemoryMapHob *)*hob_addr;
printk(BIOS_DEBUG, "================== MEMORY MAP HOB DATA ==================\n");
printk(BIOS_DEBUG, "hob: %p, structure size: 0x%lx\n", hob, sizeof(*hob));
printk(BIOS_DEBUG,
"\tlowMemBase: 0x%x, lowMemSize: 0x%x, highMemBase: 0x%x, "
"highMemSize: 0x%x\n",
hob->lowMemBase, hob->lowMemSize, hob->highMemBase, hob->highMemSize);
printk(BIOS_DEBUG, "\tmemSize: 0x%x, memFreq: 0x%x\n", hob->memSize, hob->memFreq);
printk(BIOS_DEBUG, "\tNumChPerMC: %d\n", hob->NumChPerMC);
printk(BIOS_DEBUG, "\tSystemMemoryMapElement Entries: %d, entry size: %ld\n",
hob->numberEntries, sizeof(SYSTEM_MEMORY_MAP_ELEMENT));
for (int e = 0; e < hob->numberEntries; ++e) {
const struct SystemMemoryMapElement *mem_element = &hob->Element[e];
printk(BIOS_DEBUG,
"\t\tmemory_map %d, SocketId: 0x%x, BaseAddress: 0x%x, ElementSize: 0x%x, Type: 0x%x\n",
e, mem_element->SocketId, mem_element->BaseAddress,
mem_element->ElementSize, mem_element->Type);
}
printk(BIOS_DEBUG,
"^^^ MEMMAP_SOCKET: %ld, ChannelDevice: %ld, MEMMAP_DIMM_DEVICE_INFO_STRUCT: %ld\n",
sizeof(MEMMAP_SOCKET), sizeof(struct ChannelDevice),
sizeof(MEMMAP_DIMM_DEVICE_INFO_STRUCT));
printk(BIOS_DEBUG, "^^^ Element Offset: %ld\n",
offsetof(SYSTEM_MEMORY_MAP_HOB, Element));
printk(BIOS_DEBUG, "^^^ Socket Offset: %ld\n",
offsetof(SYSTEM_MEMORY_MAP_HOB, Socket));
printk(BIOS_DEBUG, "^^^ ChannelInfo Offset: %ld\n",
offsetof(MEMMAP_SOCKET, ChannelInfo));
printk(BIOS_DEBUG, "^^^ DimmInfo Offset: %ld\n",
offsetof(struct ChannelDevice, DimmInfo));
printk(BIOS_DEBUG, "^^^ DimmSize Offset: %ld\n",
offsetof(struct DimmDevice, DimmSize));
for (int s = 0; s < MAX_SOCKET; ++s) {
if (!hob->Socket[s].SocketEnabled)
continue;
for (int ch = 0; ch < MAX_CH; ++ch) {
if (!hob->Socket[s].ChannelInfo[ch].Enabled)
continue;
for (int dimm = 0; dimm < MAX_DIMM; ++dimm) {
if (!hob->Socket[s].ChannelInfo[ch].DimmInfo[dimm].Present)
continue;
printk(BIOS_DEBUG,
"\tsocket: %d, ch: %d, dimm: %d, enabled: %d, DimmSize: 0x%x\n",
s, ch, dimm,
hob->Socket[s].ChannelInfo[ch].DimmInfo[dimm].Enabled,
hob->Socket[s].ChannelInfo[ch].DimmInfo[dimm].DimmSize);
}
}
}
printk(BIOS_DEBUG, "\tBiosFisVersion: 0x%x\n", hob->BiosFisVersion);
printk(BIOS_DEBUG, "\tMmiohBase: 0x%x\n", hob->MmiohBase);
hexdump(hob, sizeof(*hob));
}
void soc_display_iio_universal_data_hob(const IIO_UDS *hob)
{
printk(BIOS_DEBUG, "===================== IIO_UDS HOB DATA =====================\n");
printk(BIOS_DEBUG, "hob: %p, structure size: 0x%lx\n", hob, sizeof(*hob));
printk(BIOS_DEBUG, "\t===================== SYSTEM STATUS =====================\n");
printk(BIOS_DEBUG, "\tnumCpus: 0x%x\n", hob->SystemStatus.numCpus);
printk(BIOS_DEBUG, "\ttolmLimit: 0x%x\n", hob->SystemStatus.tolmLimit);
printk(BIOS_DEBUG, "\t===================== PLATFORM DATA =====================\n");
printk(BIOS_DEBUG, "\tPlatGlobalIoBase: 0x%x\n", hob->PlatformData.PlatGlobalIoBase);
printk(BIOS_DEBUG, "\tPlatGlobalIoLimit: 0x%x\n", hob->PlatformData.PlatGlobalIoLimit);
printk(BIOS_DEBUG, "\tPlatGlobalMmio32Base: 0x%x\n",
hob->PlatformData.PlatGlobalMmio32Base);
printk(BIOS_DEBUG, "\tPlatGlobalMmio32Limit: 0x%x\n",
hob->PlatformData.PlatGlobalMmio32Limit);
printk(BIOS_DEBUG, "\tPlatGlobalMmio64Base: 0x%llx\n",
hob->PlatformData.PlatGlobalMmio64Base);
printk(BIOS_DEBUG, "\tPlatGlobalMmio64Limit: 0x%llx\n",
hob->PlatformData.PlatGlobalMmio64Limit);
printk(BIOS_DEBUG, "\tMemTsegSize: 0x%x\n", hob->PlatformData.MemTsegSize);
printk(BIOS_DEBUG, "\tPciExpressBase: 0x%llx\n", hob->PlatformData.PciExpressBase);
printk(BIOS_DEBUG, "\tPciExpressSize: 0x%x\n", hob->PlatformData.PciExpressSize);
printk(BIOS_DEBUG, "\tMemTolm: 0x%x\n", hob->PlatformData.MemTolm);
printk(BIOS_DEBUG, "\tnumofIIO: 0x%x\n", hob->PlatformData.numofIIO);
printk(BIOS_DEBUG, "\tMaxBusNumber: 0x%x\n", hob->PlatformData.MaxBusNumber);
printk(BIOS_DEBUG, "\tIoGranularity: 0x%x\n", hob->PlatformData.IoGranularity);
printk(BIOS_DEBUG, "\tMmiolGranularity: 0x%x\n", hob->PlatformData.MmiolGranularity);
printk(BIOS_DEBUG, "\tMmiohGranularity: hi: 0x%x, lo:0x%x\n",
hob->PlatformData.MmiohGranularity.hi, hob->PlatformData.MmiohGranularity.lo);
for (uint8_t s = 0; s < hob->PlatformData.numofIIO; ++s) {
printk(BIOS_DEBUG, "\t============ Socket %d Info ================\n", s);
printk(BIOS_DEBUG, "\tValid: 0x%x\n", hob->PlatformData.IIO_resource[s].Valid);
printk(BIOS_DEBUG, "\tSocketID: 0x%x\n",
hob->PlatformData.IIO_resource[s].SocketID);
printk(BIOS_DEBUG, "\tBusBase: 0x%x\n",
hob->PlatformData.IIO_resource[s].BusBase);
printk(BIOS_DEBUG, "\tBusLimit: 0x%x\n",
hob->PlatformData.IIO_resource[s].BusLimit);
printk(BIOS_DEBUG, "\tPciResourceIoBase: 0x%x\n",
hob->PlatformData.IIO_resource[s].PciResourceIoBase);
printk(BIOS_DEBUG, "\tPciResourceIoLimit: 0x%x\n",
hob->PlatformData.IIO_resource[s].PciResourceIoLimit);
printk(BIOS_DEBUG, "\tIoApicBase: 0x%x\n",
hob->PlatformData.IIO_resource[s].IoApicBase);
printk(BIOS_DEBUG, "\tIoApicLimit: 0x%x\n",
hob->PlatformData.IIO_resource[s].IoApicLimit);
printk(BIOS_DEBUG, "\tMmio32Base: 0x%x\n",
hob->PlatformData.IIO_resource[s].Mmio32Base);
printk(BIOS_DEBUG, "\tMmio32Limit: 0x%x\n",
hob->PlatformData.IIO_resource[s].Mmio32Limit);
printk(BIOS_DEBUG, "\tMmio64Base: 0x%llx\n",
hob->PlatformData.IIO_resource[s].Mmio64Base);
printk(BIOS_DEBUG, "\tMmio64Limit: 0x%llx\n",
hob->PlatformData.IIO_resource[s].Mmio64Limit);
printk(BIOS_DEBUG, "\t============ Stack Info ================\n");
for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) {
const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x];
printk(BIOS_DEBUG, "\t\t========== Stack %d ===============\n", x);
printk(BIOS_DEBUG, "\t\tPersonality: 0x%x\n", ri->Personality);
printk(BIOS_DEBUG, "\t\tBusBase: 0x%x\n", ri->BusBase);
printk(BIOS_DEBUG, "\t\tBusLimit: 0x%x\n", ri->BusLimit);
printk(BIOS_DEBUG, "\t\tIoBase: 0x%x\n", ri->IoBase);
printk(BIOS_DEBUG, "\t\tIoLimit: 0x%x\n", ri->IoLimit);
printk(BIOS_DEBUG, "\t\tPciResourceIoBase: 0x%x\n",
ri->PciResourceIoBase);
printk(BIOS_DEBUG, "\t\tPciResourceIoLimit: 0x%x\n",
ri->PciResourceIoLimit);
printk(BIOS_DEBUG, "\t\tIoApicBase: 0x%x\n", ri->IoApicBase);
printk(BIOS_DEBUG, "\t\tIoApicLimit: 0x%x\n", ri->IoApicLimit);
printk(BIOS_DEBUG, "\t\tMmio32Base: 0x%x\n", ri->Mmio32Base);
printk(BIOS_DEBUG, "\t\tMmio32Limit: 0x%x\n", ri->Mmio32Limit);
printk(BIOS_DEBUG, "\t\tPciResourceMem32Base: 0x%x\n",
ri->PciResourceMem32Base);
printk(BIOS_DEBUG, "\t\tPciResourceMem32Limit: 0x%x\n",
ri->PciResourceMem32Limit);
printk(BIOS_DEBUG, "\t\tMmio64Base: 0x%llx\n", ri->Mmio64Base);
printk(BIOS_DEBUG, "\t\tMmio64Limit: 0x%llx\n", ri->Mmio64Limit);
printk(BIOS_DEBUG, "\t\tPciResourceMem64Base: 0x%llx\n",
ri->PciResourceMem64Base);
printk(BIOS_DEBUG, "\t\tPciResourceMem64Limit: 0x%llx\n",
ri->PciResourceMem64Limit);
printk(BIOS_DEBUG, "\t\tVtdBarAddress: 0x%x\n", ri->VtdBarAddress);
}
printk(BIOS_DEBUG, "\t============ PcieInfo ================\n");
IIO_RESOURCE_INSTANCE iio_resource = hob->PlatformData.IIO_resource[s];
for (int p = 0; p < NUMBER_PORTS_PER_SOCKET; ++p) {
printk(BIOS_DEBUG, "\t\tPort: %d, Device: 0x%x, Function: 0x%x\n", p,
iio_resource.PcieInfo.PortInfo[p].Device,
iio_resource.PcieInfo.PortInfo[p].Function);
}
}
hexdump(hob, sizeof(*hob));
}
static void soc_display_cxlnode_hob(const CXL_NODE_SOCKET *hob)
{
printk(BIOS_DEBUG, "===================== CXLNODE HOB DATA =====================\n");
printk(BIOS_DEBUG, "hob: %p, structure size: 0x%lx\n", hob, sizeof(*hob) * MAX_SOCKET);
for (uint8_t skt_id = 0; skt_id < MAX_SOCKET; skt_id++) {
printk(BIOS_DEBUG, "\tSocket:%d, CxlNodeCount: 0x%x\n", skt_id,
hob[skt_id].CxlNodeCount);
for (uint8_t i = 0; i < hob[skt_id].CxlNodeCount; ++i) {
printk(BIOS_DEBUG, "\tCxlNodeInfo[%d]:\n", i);
const CXL_NODE_INFO node = hob[skt_id].CxlNodeInfo[i];
printk(BIOS_DEBUG, "\t\tSerialNumber: 0x%llx\n", node.SerialNumber);
printk(BIOS_DEBUG, "\t\tVendorId: 0x%x\n", node.VendorId);
printk(BIOS_DEBUG, "\t\tAttr: 0x%x\n", node.Attr);
printk(BIOS_DEBUG, "\t\tAddress: 0x%x\n", node.Address);
printk(BIOS_DEBUG, "\t\tSize: 0x%x\n", node.Size);
printk(BIOS_DEBUG, "\t\tWays: 0x%x\n", node.Ways);
printk(BIOS_DEBUG, "\t\tSocketBitmap: 0x%x\n", node.SocketBitmap);
printk(BIOS_DEBUG,
"\t\tPerfData format: RdLatency(0.1ns), WrLatency(0.1ns), RdBW(100MB/s), WrBW(100MB/s)\n");
printk(BIOS_DEBUG,
"\t\tEfiMemType and PerfData are invalid for SPR-SP.\n");
}
}
hexdump(hob, sizeof(*hob) * MAX_SOCKET);
}
void soc_display_hob(const struct hob_header *hob)
{
uint8_t *guid;
if (hob->type != HOB_TYPE_GUID_EXTENSION)
return;
guid = (uint8_t *)fsp_hob_header_to_resource(hob);
if (fsp_guid_compare(guid, fsp_hob_iio_uds_guid))
soc_display_iio_universal_data_hob((const IIO_UDS *)(guid + 16));
else if (fsp_guid_compare(guid, fsp_hob_memmap_guid))
soc_display_memmap_hob((const struct SystemMemoryMapHob **)(guid + 16));
else if (fsp_guid_compare(guid, fsp_hob_cxlnode_guid))
soc_display_cxlnode_hob((const CXL_NODE_SOCKET *)(guid + 16));
}

View File

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_CRASHLOG_H_
#define _SOC_CRASHLOG_H_
void disable_cpu_crashlog(void);
#endif /* _SOC_CRASHLOG_H_ */

View File

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _SPR_DDR_H_
#define _SPR_DDR_H_
#include <types.h>
/* SPD Byte 11: Module Nominal Voltage
* currently DDR4 only supports 1.2V, DDR5 only supports 1.1V. */
#define SPD_VDD_DDR4 3
#define SPD_VDD_DDR5 0
#define SPD_TYPE_DDR5 0x12
/* DDR_*_TCK_MIN are in picoseconds */
#define DDR_1000_TCK_MIN 2000
#define DDR_1066_TCK_MIN 1875
#define DDR_1200_TCK_MIN 1667
#define DDR_1333_TCK_MIN 1500
#define DDR_1400_TCK_MIN 1429
#define DDR_1600_TCK_MIN 1250
#define DDR_1800_TCK_MIN 1110
#define DDR_1866_TCK_MIN 1071
#define DDR_2000_TCK_MIN 1000
#define DDR_2133_TCK_MIN 938
#define DDR_2200_TCK_MIN 909
#define DDR_2400_TCK_MIN 833
#define DDR_2600_TCK_MIN 769
#define DDR_2666_TCK_MIN 750
#define DDR_2800_TCK_MIN 714
#define DDR_2933_TCK_MIN 682
#define DDR_3000_TCK_MIN 667
#define DDR_3200_TCK_MIN 625
#define DDR_3400_TCK_MIN 589
#define DDR_3466_TCK_MIN 577
#define DDR_3600_TCK_MIN 556
#define DDR_3733_TCK_MIN 536
#define DDR_3800_TCK_MIN 527
#define DDR_4000_TCK_MIN 500
#define DDR_4200_TCK_MIN 477
#define DDR_4266_TCK_MIN 469
#define DDR_4400_TCK_MIN 455
#define DDR_4800_TCK_MIN 417
#define DDR_5200_TCK_MIN 385
#define DDR_5600_TCK_MIN 358
#define DDR_6000_TCK_MIN 334
#define DDR_6400_TCK_MIN 313
#define DDR_6800_TCK_MIN 295
#define DDR_7200_TCK_MIN 278
#define DDR_7600_TCK_MIN 264
#define DDR_8000_TCK_MIN 250
#define DDR_8400_TCK_MIN 239
unsigned int get_max_memory_speed(unsigned int commonTck);
unsigned int get_ddr_millivolt(unsigned int ddr_voltage);
bool mainboard_dimm_slot_exists(uint8_t socket, uint8_t channel, uint8_t slot);
#endif /* _SPR_DDR_H_ */

View File

@ -0,0 +1,233 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_PCI_DEVS_H_
#define _SOC_PCI_DEVS_H_
#include <device/pci_def.h>
#include <types.h>
#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_##slot, 0)
#define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_##slot, func)
#if !defined(__SIMPLE_DEVICE__)
#include <device/device.h>
#define _SA_DEV(slot) pcidev_path_on_root_debug(_SA_DEVFN(slot), __func__)
#define _PCH_DEV(slot, func) pcidev_path_on_root_debug(_PCH_DEVFN(slot, func), __func__)
#else
#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_##slot, 0)
#define _PCH_DEV(slot, func) PCI_DEV(0, PCH_DEV_SLOT_##slot, func)
#endif
#define UNCORE_BUS_0 0
#define UNCORE_BUS_1 1
/* UBOX Registers [B:30, D:0, F:1] */
#define UBOX_DECS_DEV 0
#define UBOX_URACU_FUNC 1
#define SMM_FEATURE_CONTROL 0x8c
#define SMM_CODE_CHK_EN BIT(2)
#define SMM_FEATURE_CONTROL_LOCK BIT(0)
/* 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
#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_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_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_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_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_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_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_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
/* PCH Device info */
#define XHCI_BUS_NUMBER 0x0
#define PCH_DEV_SLOT_XHCI 0x14
#define XHCI_FUNC_NUM 0x0
#define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0)
#define PCH_DEV_XHCI _PCH_DEV(XHCI, 0)
#define PCH_DEVFN_THERMAL _PCH_DEVFN(XHCI, 2)
#define PCH_DEV_SLOT_CSE 0x16
#define PCH_DEVFN_CSE _PCH_DEVFN(CSE, 0)
#define PCH_DEVFN_CSE_2 _PCH_DEVFN(CSE, 1)
#define PCH_DEVFN_CSE_3 _PCH_DEVFN(CSE, 4)
#define PCH_DEV_CSE _PCH_DEV(CSE, 0)
#define PCH_DEV_CSE_2 _PCH_DEV(CSE, 1)
#define PCH_DEV_CSE_3 _PCH_DEV(CSE, 4)
#define PCH_DEV_SLOT_LPC 0x1f
#define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0)
#define PCH_DEVFN_P2SB _PCH_DEVFN(LPC, 1)
#define PCH_DEVFN_PMC _PCH_DEVFN(LPC, 2)
#define PCH_DEVFN_SMBUS _PCH_DEVFN(LPC, 4)
#define PCH_DEVFN_SPI _PCH_DEVFN(LPC, 5)
#define PCH_DEV_LPC _PCH_DEV(LPC, 0)
#define PCH_DEV_P2SB _PCH_DEV(LPC, 1)
#define PCH_DEV_PMC _PCH_DEV(LPC, 2)
#define PCH_DEV_SMBUS _PCH_DEV(LPC, 4)
#define PCH_DEV_SPI _PCH_DEV(LPC, 5)
#define HPET_BUS_NUM 0x0
#define HPET_DEV_NUM PCH_DEV_SLOT_LPC
#define HPET0_FUNC_NUM 0x00
#define PCH_IOAPIC_BUS_NUMBER 0xF0
#define PCH_IOAPIC_DEV_NUM 0x1F
#define PCH_IOAPIC_FUNC_NUM 0x00
// ========== IOAPIC Definitions for DMAR/ACPI ========
#define PCH_IOAPIC_ID 0x08
/* 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_ */

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_UTIL_H_
#define _SOC_UTIL_H_
#include <hob_iiouds.h>
#include <hob_memmap.h>
#include <hob_cxlnode.h>
#include <hob_systeminfo.h>
#include <hob_enhancedwarningloglib.h>
const struct SystemMemoryMapHob *get_system_memory_map(void);
const struct SystemMemoryMapElement *get_system_memory_map_elment(uint8_t *num);
uint32_t get_socket_stack_busno(uint32_t socket, uint32_t stack);
bool is_iio_cxl_stack_res(const STACK_RES *res);
void soc_display_iio_universal_data_hob(const IIO_UDS *hob);
void soc_display_memmap_hob(const struct SystemMemoryMapHob **hob_addr);
const CXL_NODE_SOCKET *get_cxl_node(void);
uint8_t get_cxl_node_count(void);
const SYSTEM_INFO_VAR *get_system_info_hob(void);
const EWL_PRIVATE_DATA *get_ewl_hob(void);
uint32_t get_ubox_busno(uint32_t socket, uint8_t offset);
uint32_t get_socket_ubox_busno(uint32_t socket);
void check_fsp_error(void);
void mainboard_fsp_error_handle(void);
#endif /* _SOC_UTIL_H_ */

View File

@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _XHCI_H_
#define _XHCI_H_
#include <types.h>
#define USB2_OC_PIN_0 0x90A4
#define USB2_OC_PIN_1 0x90A8
#define USB2_OC_PIN_2 0x90AC
#define USB2_OC_PIN_3 0x90B0
#define USB2_OC_PIN_4 0x90B4
#define USB2_OC_PIN_5 0x90B8
#define USB2_OC_PIN_6 0x90BC
#define USB2_OC_PIN_7 0x90C0
#define USB3_OC_PIN_0 0x9124
#define USB3_OC_PIN_1 0x9128
#define USB3_OC_PIN_2 0x912C
#define USB3_OC_PIN_3 0x9130
#define USB3_OC_PIN_4 0x9134
#define USB3_OC_PIN_5 0x9138
#define USB3_OC_PIN_6 0x913C
#define USB3_OC_PIN_7 0x9140
#define USB_PORT_0 BIT(0)
#define USB_PORT_1 BIT(1)
#define USB_PORT_2 BIT(2)
#define USB_PORT_3 BIT(3)
#define USB_PORT_4 BIT(4)
#define USB_PORT_5 BIT(5)
#define USB_PORT_6 BIT(6)
#define USB_PORT_7 BIT(7)
#define USB_PORT_8 BIT(8)
#define USB_PORT_9 BIT(9)
#define USB_PORT_10 BIT(10)
#define USB_PORT_11 BIT(11)
#define USB_PORT_12 BIT(12)
#define USB_PORT_13 BIT(13)
#define USB_PORT_14 BIT(14)
#define USB_PORT_15 BIT(15)
#define USB_PORT_NONE 0
#define OCCFGDONE BIT(31)
struct usb_oc_mapping {
uint32_t pin;
uint32_t port;
};
void write_usb_oc_mapping(const struct usb_oc_mapping *config, uint8_t pins);
void lock_oc_cfg(bool lock);
#endif /* _XHCI_H_ */

View File

@ -0,0 +1,319 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h>
#include <cpu/cpu.h>
#include <cpu/intel/cpu_ids.h>
#include <arch/romstage.h>
#include <console/console.h>
#include <cbmem.h>
#include <drivers/vpd/vpd.h>
#include <drivers/ocp/include/vpd.h>
#include <security/intel/txt/txt.h>
#include <fsp/api.h>
#include <fsp/util.h>
#include <hob_iiouds.h>
#include <hob_memmap.h>
#include <soc/romstage.h>
#include <soc/pci_devs.h>
#include <soc/intel/common/smbios.h>
#include <string.h>
#include <soc/soc_util.h>
#include <soc/ddr.h>
#include "chip.h"
/* Initialize to all zero first */
static UPD_IIO_PCIE_PORT_CONFIG spr_iio_bifur_table[CONFIG_MAX_SOCKET_UPD];
static UINT8 deemphasis_list[CONFIG_MAX_SOCKET_UPD * MAX_IIO_PORTS_PER_SOCKET];
void __weak mainboard_memory_init_params(FSPM_UPD *mupd)
{
/* Default weak implementation */
}
bool __weak mainboard_dimm_slot_exists(uint8_t socket, uint8_t channel, uint8_t dimm)
{
return false;
}
/*
* Search from VPD_RW first then VPD_RO for UPD config variables,
* overwrites them from VPD if it's found.
*/
static void config_upd_from_vpd(FSPM_UPD *mupd)
{
uint8_t val;
int val_int, cxl_mode;
/* Send FSP log message to SOL */
if (vpd_get_bool(FSP_LOG, VPD_RW_THEN_RO, &val))
mupd->FspmConfig.SerialIoUartDebugEnable = val;
else {
printk(BIOS_INFO,
"Not able to get VPD %s, default set "
"SerialIoUartDebugEnable to %d\n",
FSP_LOG, FSP_LOG_DEFAULT);
mupd->FspmConfig.SerialIoUartDebugEnable = FSP_LOG_DEFAULT;
}
if (mupd->FspmConfig.SerialIoUartDebugEnable) {
/* FSP memory debug log level */
if (vpd_get_int(FSP_MEM_LOG_LEVEL, VPD_RW_THEN_RO, &val_int)) {
if (val_int < 0 || val_int > 4) {
printk(BIOS_DEBUG,
"Invalid serialDebugMsgLvl value from VPD: "
"%d\n",
val_int);
val_int = FSP_MEM_LOG_LEVEL_DEFAULT;
}
printk(BIOS_DEBUG, "Setting serialDebugMsgLvl to %d\n", val_int);
mupd->FspmConfig.serialDebugMsgLvl = (uint8_t)val_int;
} else {
printk(BIOS_INFO,
"Not able to get VPD %s, default set "
"DebugPrintLevel to %d\n",
FSP_MEM_LOG_LEVEL, FSP_MEM_LOG_LEVEL_DEFAULT);
mupd->FspmConfig.serialDebugMsgLvl = FSP_MEM_LOG_LEVEL_DEFAULT;
}
/* If serialDebugMsgLvl less than 1, disable FSP memory train results */
if (mupd->FspmConfig.serialDebugMsgLvl <= 1) {
printk(BIOS_DEBUG, "Setting serialDebugMsgLvlTrainResults to 0\n");
mupd->FspmConfig.serialDebugMsgLvlTrainResults = 0x0;
}
}
/* FSP Dfx PMIC Secure mode */
if (vpd_get_int(FSP_PMIC_SECURE_MODE, VPD_RW_THEN_RO, &val_int)) {
if (val_int < 0 || val_int > 2) {
printk(BIOS_DEBUG,
"Invalid PMIC secure mode value from VPD: "
"%d\n",
val_int);
val_int = FSP_PMIC_SECURE_MODE_DEFAULT;
}
printk(BIOS_DEBUG, "Setting PMIC secure mode to %d\n", val_int);
mupd->FspmConfig.DfxPmicSecureMode = (uint8_t)val_int;
} else {
printk(BIOS_INFO,
"Not able to get VPD %s, default set "
"PMIC secure mode to %d\n",
FSP_PMIC_SECURE_MODE, FSP_PMIC_SECURE_MODE_DEFAULT);
mupd->FspmConfig.DfxPmicSecureMode = FSP_PMIC_SECURE_MODE_DEFAULT;
}
cxl_mode = get_cxl_mode_from_vpd();
if (cxl_mode == CXL_SYSTEM_MEMORY || cxl_mode == CXL_SPM)
mupd->FspmConfig.DfxCxlType3LegacyEn = 1;
else /* Disable CXL */
mupd->FspmConfig.DfxCxlType3LegacyEn = 0;
if (CONFIG(INTEL_TXT)) {
/* Configure for error injection test */
mupd->FspmConfig.DFXEnable = skip_intel_txt_lockdown() ? 1 : 0;
}
}
/* Initialize non-zero default UPD values for IIO */
static void initialize_iio_upd(FSPM_UPD *mupd)
{
unsigned int port, socket;
mupd->FspmConfig.IioPcieConfigTablePtr = (UINT32)spr_iio_bifur_table;
mupd->FspmConfig.IioPcieConfigTableNumber = CONFIG_MAX_SOCKET_UPD;
UPD_IIO_PCIE_PORT_CONFIG *PciePortConfig =
(UPD_IIO_PCIE_PORT_CONFIG *)spr_iio_bifur_table;
/* Initialize non-zero default UPD values */
for (socket = 0; socket < CONFIG_MAX_SOCKET_UPD; socket++) {
for (port = 0; port < MAX_IIO_PORTS_PER_SOCKET; port++) {
PciePortConfig[socket].PcieMaxPayload[port] = 0x7; /* Auto */
PciePortConfig[socket].DfxDnTxPresetGen3[port] = 0xff; /* Auto */
}
PciePortConfig[socket].PcieGlobalAspm = 0x1; /* Enable ASPM */
PciePortConfig[socket].PcieMaxReadRequestSize = 0x5;
}
mupd->FspmConfig.DeEmphasisPtr = (UINT32)deemphasis_list;
mupd->FspmConfig.DeEmphasisNumber = CONFIG_MAX_SOCKET_UPD * MAX_IIO_PORTS_PER_SOCKET;
UINT8 *DeEmphasisConfig = (UINT8 *)deemphasis_list;
for (port = 0; port < CONFIG_MAX_SOCKET_UPD * MAX_IIO_PORTS_PER_SOCKET; port++)
DeEmphasisConfig[port] = 0x1;
}
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
{
FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
const config_t *config = config_of_soc();
m_cfg->DebugPrintLevel = 0xF;
m_cfg->DirectoryModeEn = 0x2;
const u8 KtiFpgaEnable[] = {0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1};
memcpy(m_cfg->KtiFpgaEnable, KtiFpgaEnable, sizeof(m_cfg->KtiFpgaEnable));
m_cfg->TscSyncEn = 0x1;
m_cfg->mmiohBase = 0x2000;
m_cfg->mmiohSize = 0x3;
m_cfg->BoardTypeBitmask = 0x11111133;
m_cfg->X2apic = config->x2apic;
printk(BIOS_INFO, "m_cfg->X2apic = 0x%x config->x2apic = 0x%x\n", m_cfg->X2apic,
config->x2apic);
m_cfg->serialDebugMsgLvl = 0x3;
m_cfg->VtdSupport = config->vtd_support;
m_cfg->SerialIoUartDebugIoBase = 0x3F8;
mupd->FspmConfig.AttemptFastBoot = 1;
mupd->FspmConfig.AttemptFastBootCold = 1;
/* Set Patrol Scrub UPD */
mupd->FspmConfig.PatrolScrubNotify = 0x1; /* 1:Enable at ReadyToBootFsp() */
mupd->FspmConfig.PatrolScrub = 0x2; /* 2:Enable during
NotifyPhase(EnumInitPhaseReadyToBoot) */
mupd->FspmConfig.ErrorCheckScrub = 1; /* Enable/Disable DDR5 Error Check
and Scrub (ECS) in FSP */
mupd->FspmConfig.PatrolScrubAddrMode = 1; /* 1:System Physical Address */
mupd->FspmConfig.PatrolScrubDuration = 24; /* unit is hour */
/* Disable below UPDs because those features should be implemented by coreboot */
mupd->FspmConfig.LockChipset = 0;
mupd->FspmConfig.ProcessorMsrLockControl = 0;
/* Don't set and signal MSR_BIOS_DONE in FSP since it should be done by coreboot */
mupd->FspmConfig.DfxDisableBiosDone = 1;
u32 cpu_id = cpu_get_cpuid();
if (cpu_id == (u32)CPUID_SAPPHIRERAPIDS_SP_D) {
printk(BIOS_DEBUG, "CPU is D stepping, setting package C state to C0/C1\n");
mupd->FspmConfig.CpuPmPackageCState = 0;
}
/* Set some common UPDs from VPD, mainboard can still override them if needed */
if (CONFIG(VPD))
config_upd_from_vpd(mupd);
initialize_iio_upd(mupd);
mainboard_memory_init_params(mupd);
}
static uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
{
switch (RasModesEnabled) {
case CH_INDEPENDENT:
return MEMORY_ARRAY_ECC_SINGLE_BIT;
case FULL_MIRROR_1LM:
case PARTIAL_MIRROR_1LM:
case FULL_MIRROR_2LM:
case PARTIAL_MIRROR_2LM:
return MEMORY_ARRAY_ECC_MULTI_BIT;
case RK_SPARE:
return MEMORY_ARRAY_ECC_SINGLE_BIT;
case CH_LOCKSTEP:
return MEMORY_ARRAY_ECC_SINGLE_BIT;
default:
return MEMORY_ARRAY_ECC_MULTI_BIT;
}
}
/* Save the DIMM information for SMBIOS table 17 */
void save_dimm_info(void)
{
struct dimm_info *dest_dimm;
struct memory_info *mem_info;
const struct SystemMemoryMapHob *hob;
MEMMAP_DIMM_DEVICE_INFO_STRUCT src_dimm;
int dimm_max, dimm_num = 0;
int index = 0;
uint8_t mem_dev_type;
uint16_t data_width;
uint32_t vdd_voltage;
hob = get_system_memory_map();
assert(hob != NULL);
/*
* Allocate CBMEM area for DIMM information used to populate SMBIOS
* table 17
*/
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
if (mem_info == NULL) {
printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
return;
}
memset(mem_info, 0, sizeof(*mem_info));
/* According to EDS doc#611488, it's 4 TB per processor. */
mem_info->max_capacity_mib = 4 * MiB * CONFIG_MAX_SOCKET;
mem_info->number_of_devices = CONFIG_DIMM_MAX;
mem_info->ecc_type = get_error_correction_type(hob->RasModesEnabled);
dimm_max = ARRAY_SIZE(mem_info->dimm);
vdd_voltage = get_ddr_millivolt(hob->DdrVoltage);
for (int soc = 0; soc < CONFIG_MAX_SOCKET; soc++) {
for (int ch = 0; ch < MAX_CH; ch++) {
for (int dimm = 0; dimm < MAX_DIMM; dimm++) {
if (index >= dimm_max) {
printk(BIOS_WARNING, "Too many DIMMs info for %s.\n",
__func__);
return;
}
src_dimm = hob->Socket[soc].ChannelInfo[ch].DimmInfo[dimm];
if (src_dimm.Present) {
dest_dimm = &mem_info->dimm[index];
index++;
} else if (mainboard_dimm_slot_exists(soc, ch, dimm)) {
dest_dimm = &mem_info->dimm[index];
index++;
/* Save DIMM Locator information for SMBIOS Type 17 */
dest_dimm->dimm_size = 0;
dest_dimm->soc_num = soc;
dest_dimm->channel_num = ch;
dest_dimm->dimm_num = dimm;
continue;
} else {
/* Ignore DIMM that isn't present and doesn't exist on
the board. */
continue;
}
dest_dimm->max_speed_mts =
get_max_memory_speed(src_dimm.commonTck);
dest_dimm->configured_speed_mts = hob->memFreq;
dest_dimm->soc_num = soc;
if (hob->DramType == SPD_TYPE_DDR5) {
/* hard-coded memory device type as DDR5 */
mem_dev_type = 0x22;
data_width = 64;
} else {
/* hard-coded memory device type as DDR4 */
mem_dev_type = 0x1A;
data_width = 64;
}
dimm_info_fill(
dest_dimm, src_dimm.DimmSize << 6, mem_dev_type,
hob->memFreq, /* replaced by configured_speed_mts */
src_dimm.NumRanks,
ch, /* for mainboard locator string override */
dimm, /* for mainboard locator string override */
(const char *)&src_dimm.PartNumber[0],
sizeof(src_dimm.PartNumber),
(const uint8_t *)&src_dimm.serialNumber[0], data_width,
vdd_voltage, true, /* hard-coded as ECC supported */
src_dimm.VendorID, src_dimm.actKeyByte2, 0);
dimm_num++;
}
}
}
mem_info->dimm_cnt = index; /* Number of DIMM slots found */
printk(BIOS_DEBUG, "%d Installed DIMMs found\n", dimm_num);
}
void fsp_check_for_error(void)
{
check_fsp_error();
}

View File

@ -0,0 +1,177 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h>
#include <device/device.h>
#include <device/pci.h>
#include <hob_cxlnode.h>
#include <intelblocks/cpulib.h>
#include <soc/cpu.h>
#include <soc/msr.h>
#include <soc/numa.h>
#include <soc/pci_devs.h>
#include <soc/soc_util.h>
#include <soc/util.h>
#include <stdlib.h>
#include <string.h>
const EWL_PRIVATE_DATA *get_ewl_hob(void)
{
size_t hob_size;
static const EWL_PRIVATE_DATA *hob;
const uint8_t ewl_id_hob_guid[16] = FSP_HOB_EWLID_GUID;
if (hob != NULL)
return hob;
hob = fsp_find_extension_hob_by_guid(ewl_id_hob_guid, &hob_size);
assert(hob != NULL && hob_size != 0);
return hob;
}
const SYSTEM_INFO_VAR *get_system_info_hob(void)
{
size_t hob_size;
static const SYSTEM_INFO_VAR *hob;
const uint8_t system_info_hob_guid[16] = FSP_HOB_SYSTEMINFO_GUID;
if (hob != NULL)
return hob;
hob = fsp_find_extension_hob_by_guid(system_info_hob_guid, &hob_size);
assert(hob != NULL && hob_size != 0);
return hob;
}
const struct SystemMemoryMapHob *get_system_memory_map(void)
{
size_t hob_size;
const uint8_t mem_hob_guid[16] = FSP_SYSTEM_MEMORYMAP_HOB_GUID;
const struct SystemMemoryMapHob **memmap_addr;
memmap_addr = (const struct SystemMemoryMapHob **)fsp_find_extension_hob_by_guid(
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;
}
bool is_iio_stack_res(const STACK_RES *res)
{
return res->Personality == TYPE_UBOX_IIO || res->Personality == TYPE_DINO;
}
/*
* Given a stack resource, figure out whether the corresponding stack has
* CXL device.
* It goes through pds (proximity domains) structure to see if there is any
* generic initiator has device with bus # falls between bus base and
* bus limit.
*/
bool is_iio_cxl_stack_res(const STACK_RES *res)
{
for (uint8_t i = 0; i < pds.num_pds; i++) {
if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR)
continue;
uint32_t bus = pds.pds[i].device_handle >> 20;
if (bus >= res->BusBase && bus <= res->BusLimit)
return true;
}
return false;
}
const CXL_NODE_SOCKET *get_cxl_node(void)
{
size_t hob_size;
static const CXL_NODE_SOCKET *hob;
static bool hob_check = 0;
const uint8_t fsp_hob_cxl_node_socket_guid[16] = FSP_HOB_CXLNODE_GUID;
if (hob_check == 1)
return hob;
hob = fsp_find_extension_hob_by_guid(fsp_hob_cxl_node_socket_guid, &hob_size);
hob_check = 1;
if (hob == NULL || hob_size == 0)
printk(BIOS_DEBUG,
"FSP_HOB_CXLNODE_GUID not found: CXL may not be installed\n");
return hob;
}
uint8_t get_cxl_node_count(void)
{
const CXL_NODE_SOCKET *hob = get_cxl_node();
uint8_t count = 0;
if (hob != NULL) {
for (uint8_t skt_id = 0; skt_id < MAX_SOCKET; skt_id++)
count += hob[skt_id].CxlNodeCount;
}
return count;
}
uint32_t get_socket_stack_busno(uint32_t socket, uint32_t stack)
{
const IIO_UDS *hob = get_iio_uds();
assert(socket < hob->SystemStatus.numCpus && stack < MAX_LOGIC_IIO_STACK);
return hob->PlatformData.IIO_resource[socket].StackRes[stack].BusBase;
}
uint32_t get_ubox_busno(uint32_t socket, uint8_t offset)
{
const IIO_UDS *hob = get_iio_uds();
assert(socket < hob->SystemStatus.numCpus);
for (int stack = 0; stack < MAX_LOGIC_IIO_STACK; ++stack) {
if (hob->PlatformData.IIO_resource[socket].StackRes[stack].Personality
== TYPE_UBOX)
return (hob->PlatformData.IIO_resource[socket].StackRes[stack].BusBase
+ offset);
}
die("Unable to locate UBOX BUS NO");
}
uint32_t get_socket_ubox_busno(uint32_t socket)
{
return get_ubox_busno(socket, UNCORE_BUS_1);
}
/* mainboard can override this function for their own handling, such as write a BMC SEL. */
void __weak mainboard_fsp_error_handle(void)
{
die("ERROR: FSP reported an error(s) after running!");
}
void check_fsp_error(void)
{
bool fsp_found_error = fsp_find_error_info();
if (fsp_found_error)
mainboard_fsp_error_handle();
}
void bios_done_msr(void *unused)
{
msr_t msr = rdmsr(MSR_BIOS_DONE);
if (!(msr.lo & XEON_SP_ENABLE_IA_UNTRUSTED)) { /* if already locked skip update */
msr.lo |= XEON_SP_ENABLE_IA_UNTRUSTED;
wrmsr(MSR_BIOS_DONE, msr);
}
}

View File

@ -0,0 +1,139 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <fsp/util.h>
#include <lib.h>
#define DUMP_UPD(old, new, field) \
fsp_display_upd_value(#field, sizeof(old->field), old->field, new->field)
static void soc_display_fspm_upd_iio(const FSPM_UPD *mupd)
{
int port, socket;
UPD_IIO_PCIE_PORT_CONFIG *PciePortConfig =
(UPD_IIO_PCIE_PORT_CONFIG *)mupd->FspmConfig.IioPcieConfigTablePtr;
printk(BIOS_SPEW, "UPD values for IIO:\n");
for (socket = 0; socket < mupd->FspmConfig.IioPcieConfigTableNumber; socket++) {
printk(BIOS_SPEW, "Socket: %d\n", socket);
for (port = 0; port < MAX_IIO_PORTS_PER_SOCKET; port++) {
printk(BIOS_SPEW, "port: %d\n", port);
printk(BIOS_SPEW, "\tSLOTEIP: 0x%x\n",
PciePortConfig[socket].SLOTEIP[port]);
printk(BIOS_SPEW, "\tSLOTHPCAP: 0x%x\n",
PciePortConfig[socket].SLOTHPCAP[port]);
printk(BIOS_SPEW, "\tSLOTHPSUP: 0x%x\n",
PciePortConfig[socket].SLOTHPSUP[port]);
printk(BIOS_SPEW, "\tSLOTPIP: 0x%x\n",
PciePortConfig[socket].SLOTPIP[port]);
printk(BIOS_SPEW, "\tSLOTAIP: 0x%x\n",
PciePortConfig[socket].SLOTAIP[port]);
printk(BIOS_SPEW, "\tSLOTMRLSP: 0x%x\n",
PciePortConfig[socket].SLOTMRLSP[port]);
printk(BIOS_SPEW, "\tSLOTPCP: 0x%x\n",
PciePortConfig[socket].SLOTPCP[port]);
printk(BIOS_SPEW, "\tSLOTABP: 0x%x\n",
PciePortConfig[socket].SLOTABP[port]);
printk(BIOS_SPEW, "\tSLOTIMP: 0x%x\n",
PciePortConfig[socket].SLOTIMP[port]);
printk(BIOS_SPEW, "\tSLOTSPLS: 0x%x\n",
PciePortConfig[socket].SLOTSPLS[port]);
printk(BIOS_SPEW, "\tSLOTSPLV: 0x%x\n",
PciePortConfig[socket].SLOTSPLV[port]);
printk(BIOS_SPEW, "\tSLOTPSP: 0x%x\n",
PciePortConfig[socket].SLOTPSP[port]);
printk(BIOS_SPEW, "\tVppEnabled: 0x%x\n",
PciePortConfig[socket].VppEnabled[port]);
printk(BIOS_SPEW, "\tVppPort: 0x%x\n",
PciePortConfig[socket].VppPort[port]);
printk(BIOS_SPEW, "\tVppAddress: 0x%x\n",
PciePortConfig[socket].VppAddress[port]);
printk(BIOS_SPEW, "\tMuxAddress: 0x%x\n",
PciePortConfig[socket].MuxAddress[port]);
printk(BIOS_SPEW, "\tChannelID: 0x%x\n",
PciePortConfig[socket].ChannelID[port]);
printk(BIOS_SPEW, "\tPciePortEnable: 0x%x\n",
PciePortConfig[socket].PciePortEnable[port]);
printk(BIOS_SPEW, "\tPEXPHIDE: 0x%x\n",
PciePortConfig[socket].PEXPHIDE[port]);
printk(BIOS_SPEW, "\tHidePEXPMenu: 0x%x\n",
PciePortConfig[socket].HidePEXPMenu[port]);
printk(BIOS_SPEW, "\tPciePortOwnership: 0x%x\n",
PciePortConfig[socket].PciePortOwnership[port]);
printk(BIOS_SPEW, "\tRetimerConnectCount: 0x%x\n",
PciePortConfig[socket].RetimerConnectCount[port]);
printk(BIOS_SPEW, "\tPcieHotPlugOnPort: 0x%x\n",
PciePortConfig[socket].PcieHotPlugOnPort[port]);
printk(BIOS_SPEW, "\tVMDPortEnable: 0x%x\n",
PciePortConfig[socket].VMDPortEnable[port]);
printk(BIOS_SPEW, "\tPcieMaxPayload: 0x%x\n",
PciePortConfig[socket].PcieMaxPayload[port]);
printk(BIOS_SPEW, "\tPciePortLinkSpeed: 0x%x\n",
PciePortConfig[socket].PciePortLinkSpeed[port]);
printk(BIOS_SPEW, "\tDfxDnTxPresetGen3: 0x%x\n",
PciePortConfig[socket].DfxDnTxPresetGen3[port]);
}
for (port = 0; port < MAX_VMD_STACKS_PER_SOCKET; port++) {
printk(BIOS_SPEW, "port: %d\n", port);
printk(BIOS_SPEW, "\tVMDEnabled: 0x%x\n",
PciePortConfig[socket].VMDEnabled[port]);
printk(BIOS_SPEW, "\tVMDHotPlugEnable: 0x%x\n",
PciePortConfig[socket].VMDHotPlugEnable[port]);
}
printk(BIOS_SPEW, "ConfigIOU[0]: 0x%x\n", PciePortConfig[socket].ConfigIOU[0]);
printk(BIOS_SPEW, "ConfigIOU[1]: 0x%x\n", PciePortConfig[socket].ConfigIOU[1]);
printk(BIOS_SPEW, "ConfigIOU[2]: 0x%x\n", PciePortConfig[socket].ConfigIOU[2]);
printk(BIOS_SPEW, "ConfigIOU[3]: 0x%x\n", PciePortConfig[socket].ConfigIOU[3]);
printk(BIOS_SPEW, "ConfigIOU[4]: 0x%x\n", PciePortConfig[socket].ConfigIOU[4]);
printk(BIOS_SPEW, "PcieGlobalAspm: 0x%x\n",
PciePortConfig[socket].PcieGlobalAspm);
printk(BIOS_SPEW, "PcieMaxReadRequestSize: 0x%x\n",
PciePortConfig[socket].PcieMaxReadRequestSize);
}
UINT8 *DeEmphasisConfig = (UINT8 *)mupd->FspmConfig.DeEmphasisPtr;
for (port = 0; port < mupd->FspmConfig.DeEmphasisNumber; port++) {
printk(BIOS_SPEW, "port: %d, DeEmphasisConfig: 0x%x\n", port,
DeEmphasisConfig[port]);
}
}
/* Display the UPD parameters for MemoryInit */
void soc_display_fspm_upd_params(const FSPM_UPD *fspm_old_upd, const FSPM_UPD *fspm_new_upd)
{
const FSP_M_CONFIG *new;
const FSP_M_CONFIG *old;
old = &fspm_old_upd->FspmConfig;
new = &fspm_new_upd->FspmConfig;
printk(BIOS_DEBUG, "UPD values for MemoryInit:\n");
DUMP_UPD(old, new, DebugPrintLevel);
DUMP_UPD(old, new, DfxCxlHeaderBypass);
DUMP_UPD(old, new, DfxCxlSecLvl);
printk(BIOS_DEBUG, " Dump of original MemoryInit UPD:\n");
hexdump(fspm_old_upd, sizeof(*fspm_old_upd));
printk(BIOS_DEBUG, " Dump of updated MemoryInit UPD:\n");
hexdump(fspm_new_upd, sizeof(*fspm_new_upd));
if (CONFIG(DISPLAY_UPD_IIO_DATA))
soc_display_fspm_upd_iio(fspm_new_upd);
}
/* Display the UPD parameters for SiliconInit */
void soc_display_fsps_upd_params(const FSPS_UPD *fsps_old_upd, const FSPS_UPD *fsps_new_upd)
{
const FSP_S_CONFIG *new;
const FSP_S_CONFIG *old;
old = &fsps_old_upd->FspsConfig;
new = &fsps_new_upd->FspsConfig;
printk(BIOS_DEBUG, "UPD values for SiliconInit:\n");
hexdump(fsps_new_upd, sizeof(*fsps_new_upd));
}