coreboot/src/include/device/path.h
Jeremy Compostella 8f0b0f7f95 cpu/x86/topology: Fix FSP-S crash caused by shared core ID
This resolves a crash issue observed on Meteor Lake and introduced by
commit 70bdd2e1fa ("cpu/x86/topology:
Simplify CPU topology initialization"). This commit simplifies the
code and provides more detailed CPU topology information by
generalizing the use of the Extended Topology Enumeration Leaves
0x1f. As a result, the coreboot APIC core_id field does not provide
the fully detailed path information.

It turns out that the topology core identifier is used by the coreboot
MP service mp_get_processor_info() implementation. But the MP Service
EFI_CPU_PHYSICAL_LOCATION data structure only captures information
about the package, core, and thread. The core identifier returned to
the MP service caller must incorporate the full hierarchical path (die
group, die, module, tile, module and core).

This commit adds a new field to the cpu topology structure to
represent the core ID within the package.

For reference, here is that signature of the crash:

   LAPIC 0x40 in X2APIC mode.
   CPU Index 2 - APIC 64 Unexpected Exception:13 @ 10:69f3d1e4 - Halting
   Code: 0 eflags: 00010046 cr2: 00000000
   eax: 00000001 ebx: 69f313e8 ecx: 0000004e edx: 00000000
   edi: 69f38018 esi: 00000029 ebp: 69aeee0c esp: 69aeedc0
   [...]

The crash occurred when FSP attempted to lock the Protected
Processor Inventory Number Enable Control MSR (IA32_PPIN_CTL
0x4e).

   69f3d1d3:	8b 43 f4             	mov    -0xc(%ebx),%eax
   69f3d1d6:	89 4d c4             	mov    %ecx,-0x3c(%ebp)
   69f3d1d9:	89 45 dc             	mov    %eax,-0x24(%ebp)
   69f3d1dc:	8b 55 c4             	mov    -0x3c(%ebp),%edx
   69f3d1df:	8b 45 c0             	mov    -0x40(%ebp),%eax
   69f3d1e2:	8b 4d dc             	mov    -0x24(%ebp),%ecx
   69f3d1e5:	0f 30                	wrmsr
   69f3d1e7:	e9 ee fd ff ff       	jmp    0xfffffe39

FSP experiences issues due to attempting to lock the same register
multiple times for a single core. This is caused by an inconsistency
in the processor information data structure, where multiple cores
share the same identifier. This is not permitted and triggers a
General Protection Fault Exception.

TEST=Executing CpuFeaturesPei.efi in FSP-S does not crash on a rex
     board.

Change-Id: I06db580cddaeaf5c452fa72f131d37d10dbc5974
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/86004
Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-by: Cliff Huang <cliff.huang@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Zhixing Ma <zhixing.ma@intel.com>
2025-01-17 16:50:31 +00:00

166 lines
2.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef DEVICE_PATH_H
#define DEVICE_PATH_H
#include <stdint.h>
enum device_path_type {
DEVICE_PATH_NONE = 0,
DEVICE_PATH_ROOT,
DEVICE_PATH_PCI,
DEVICE_PATH_PNP,
DEVICE_PATH_I2C,
DEVICE_PATH_APIC,
DEVICE_PATH_DOMAIN,
DEVICE_PATH_CPU_CLUSTER,
DEVICE_PATH_CPU,
DEVICE_PATH_CPU_BUS,
DEVICE_PATH_IOAPIC,
DEVICE_PATH_GENERIC,
DEVICE_PATH_SPI,
DEVICE_PATH_USB,
DEVICE_PATH_MMIO,
DEVICE_PATH_GPIO,
DEVICE_PATH_MDIO,
DEVICE_PATH_GICC_V3,
/*
* When adding path types to this table, please also update the
* DEVICE_PATH_NAMES macro below.
*/
};
#define DEVICE_PATH_NAMES { \
"DEVICE_PATH_NONE", \
"DEVICE_PATH_ROOT", \
"DEVICE_PATH_PCI", \
"DEVICE_PATH_PNP", \
"DEVICE_PATH_I2C", \
"DEVICE_PATH_APIC", \
"DEVICE_PATH_DOMAIN", \
"DEVICE_PATH_CPU_CLUSTER", \
"DEVICE_PATH_CPU", \
"DEVICE_PATH_CPU_BUS", \
"DEVICE_PATH_IOAPIC", \
"DEVICE_PATH_GENERIC", \
"DEVICE_PATH_SPI", \
"DEVICE_PATH_USB", \
"DEVICE_PATH_MMIO", \
"DEVICE_PATH_GPIO", \
"DEVICE_PATH_MDIO", \
"DEVICE_PATH_GICC_V3", \
}
struct domain_path {
unsigned int domain_id;
};
struct pci_path {
unsigned int devfn;
};
struct pnp_path {
unsigned int port;
unsigned int device;
};
struct i2c_path {
unsigned int device;
unsigned int mode_10bit;
};
struct spi_path {
unsigned int cs;
};
struct apic_path {
unsigned int initial_lapicid;
unsigned int apic_id;
unsigned int package_id;
unsigned int node_id;
unsigned int core_id;
unsigned int thread_id;
unsigned int module_id;
/*
* Core identifier within the package, including the die group, die, tile, module, and
* specific core.
*/
unsigned int core_id_within_package;
unsigned char core_type;
};
struct ioapic_path {
uintptr_t addr;
unsigned int ioapic_id;
unsigned int gsi_base;
};
struct cpu_cluster_path {
unsigned int cluster;
};
struct cpu_path {
unsigned int id;
};
struct cpu_bus_path {
unsigned int id;
};
struct generic_path {
unsigned int id;
unsigned int subid;
};
struct usb_path {
unsigned int port_type;
unsigned int port_id;
};
struct mmio_path {
uintptr_t addr;
};
struct gpio_path {
unsigned int id;
};
struct mdio_path {
unsigned int addr;
};
struct gicc_v3_path {
unsigned long long mpidr;
unsigned int vgic_mi;
unsigned int pi_gsiv;
};
struct device_path {
enum device_path_type type;
union {
struct pci_path pci;
struct pnp_path pnp;
struct i2c_path i2c;
struct apic_path apic;
struct ioapic_path ioapic;
struct domain_path domain;
struct cpu_cluster_path cpu_cluster;
struct cpu_path cpu;
struct cpu_bus_path cpu_bus;
struct generic_path generic;
struct spi_path spi;
struct usb_path usb;
struct mmio_path mmio;
struct gpio_path gpio;
struct mdio_path mdio;
struct gicc_v3_path gicc_v3;
};
};
#define DEVICE_PATH_MAX 40
#define BUS_PATH_MAX (DEVICE_PATH_MAX+10)
extern const char *dev_path_name(enum device_path_type type);
#endif /* DEVICE_PATH_H */