Skip to content

Commit

Permalink
soc/intel/xeon_sp/spr: Add header files and romstage code
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jonathan Zhang authored and LeanSheng committed Mar 19, 2023
1 parent ecb4a24 commit 15fc459
Show file tree
Hide file tree
Showing 11 changed files with 1,365 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/include/cpu/intel/cpu_ids.h
Expand Up @@ -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
Expand Down
93 changes: 93 additions & 0 deletions src/soc/intel/xeon_sp/spr/ddr.c
@@ -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;
}
244 changes: 244 additions & 0 deletions src/soc/intel/xeon_sp/spr/hob_display.c
@@ -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));
}
8 changes: 8 additions & 0 deletions src/soc/intel/xeon_sp/spr/include/soc/crashlog.h
@@ -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_ */

0 comments on commit 15fc459

Please sign in to comment.