Marc Jones has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/47170 )
Change subject: soc/intel/xeon_sp: Move CPU helper functions ......................................................................
soc/intel/xeon_sp: Move CPU helper functions
Continue Xeon-SP de-duplication. Move CPU helper functions from skx/ and cpx soc_util.c to common util.c. Functions only used by util.c are updated to be static.
The following functions are moved: int get_threads_per_package(void); int get_platform_thread_count(void); const IIO_UDS *get_iio_uds(void); unsigned int soc_get_num_cpus(void); void get_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits); void get_cpu_info_from_apicid(uint32_t apicid, uint32_t core_bits, uint32_t thread_bits, uint8_t *package, uint8_t *core, uint8_t *thread); void xeonsp_init_cpu_config(void);
Change-Id: I118a451b9468459cf2c2194f31da1055e1435ebe Signed-off-by: Marc Jones marcjones@sysproconsulting.com --- M src/soc/intel/xeon_sp/acpi.c M src/soc/intel/xeon_sp/cpx/cpu.c M src/soc/intel/xeon_sp/cpx/include/soc/soc_util.h M src/soc/intel/xeon_sp/cpx/soc_util.c M src/soc/intel/xeon_sp/include/soc/util.h M src/soc/intel/xeon_sp/nb_acpi.c M src/soc/intel/xeon_sp/skx/include/soc/soc_util.h M src/soc/intel/xeon_sp/skx/soc_util.c M src/soc/intel/xeon_sp/util.c 9 files changed, 147 insertions(+), 278 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/70/47170/1
diff --git a/src/soc/intel/xeon_sp/acpi.c b/src/soc/intel/xeon_sp/acpi.c index acf030b..d33d1d0 100644 --- a/src/soc/intel/xeon_sp/acpi.c +++ b/src/soc/intel/xeon_sp/acpi.c @@ -11,8 +11,9 @@ #include <soc/acpi.h> #include <soc/cpu.h> #include <soc/pci_devs.h> -#include <soc/soc_util.h> #include <soc/pm.h> +#include <soc/soc_util.h> +#include <soc/util.h> #include <string.h>
acpi_cstate_t *soc_get_cstate_map(size_t *entries) diff --git a/src/soc/intel/xeon_sp/cpx/cpu.c b/src/soc/intel/xeon_sp/cpx/cpu.c index 4e0de87..736207e 100644 --- a/src/soc/intel/xeon_sp/cpx/cpu.c +++ b/src/soc/intel/xeon_sp/cpx/cpu.c @@ -17,6 +17,7 @@ #include <soc/cpu.h> #include <soc/msr.h> #include <soc/soc_util.h> +#include <soc/util.h>
#include "chip.h"
diff --git a/src/soc/intel/xeon_sp/cpx/include/soc/soc_util.h b/src/soc/intel/xeon_sp/cpx/include/soc/soc_util.h index 5f4a6f9..8c454bb2 100644 --- a/src/soc/intel/xeon_sp/cpx/include/soc/soc_util.h +++ b/src/soc/intel/xeon_sp/cpx/include/soc/soc_util.h @@ -13,16 +13,6 @@
uint8_t get_iiostack_info(struct iiostack_resource *info);
-void xeonsp_init_cpu_config(void); -const IIO_UDS *get_iio_uds(void); -void get_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits); -void get_cpu_info_from_apicid(uint32_t apicid, uint32_t core_bits, uint32_t thread_bits, - uint8_t *package, uint8_t *core, uint8_t *thread); -/* Return socket count, as obtained from FSP HOB */ -unsigned int soc_get_num_cpus(void); - -int get_platform_thread_count(void); -int get_threads_per_package(void); const struct SystemMemoryMapHob *get_system_memory_map(void);
void set_bios_init_completion(void); diff --git a/src/soc/intel/xeon_sp/cpx/soc_util.c b/src/soc/intel/xeon_sp/cpx/soc_util.c index de6d852..149f2c0 100644 --- a/src/soc/intel/xeon_sp/cpx/soc_util.c +++ b/src/soc/intel/xeon_sp/cpx/soc_util.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h> -#include <commonlib/sort.h> #include <delay.h> #include <device/device.h> #include <device/pci.h> @@ -9,22 +8,11 @@ #include <soc/cpu.h> #include <soc/pci_devs.h> #include <soc/soc_util.h> +#include <soc/util.h> #include <stdlib.h> #include <string.h> #include <timer.h>
-int get_threads_per_package(void) -{ - unsigned int core_count, thread_count; - cpu_read_topology(&core_count, &thread_count); - return thread_count; -} - -int get_platform_thread_count(void) -{ - return soc_get_num_cpus() * get_threads_per_package(); -} - const struct SystemMemoryMapHob *get_system_memory_map(void) { size_t hob_size; @@ -41,125 +29,6 @@ return *memmap_addr; }
-void get_cpu_info_from_apicid(uint32_t apicid, uint32_t core_bits, uint32_t thread_bits, - uint8_t *package, uint8_t *core, uint8_t *thread) -{ - if (package != NULL) - *package = (apicid >> (thread_bits + core_bits)); - if (core != NULL) - *core = (uint32_t)((apicid >> thread_bits) & ~((~0) << core_bits)); - if (thread != NULL) - *thread = (uint32_t)(apicid & ~((~0) << thread_bits)); -} - -void get_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits) -{ - register int ecx; - struct cpuid_result cpuid_regs; - - /* get max index of CPUID */ - cpuid_regs = cpuid(0); - assert(cpuid_regs.eax >= 0xb); /* cpuid_regs.eax is max input value for cpuid */ - - *thread_bits = *core_bits = 0; - ecx = 0; - while (1) { - cpuid_regs = cpuid_ext(0xb, ecx); - if (ecx == 0) { - *thread_bits = (cpuid_regs.eax & 0x1f); - } else { - *core_bits = (cpuid_regs.eax & 0x1f) - *thread_bits; - break; - } - ecx++; - } -} - -const IIO_UDS *get_iio_uds(void) -{ - size_t hob_size; - const IIO_UDS *hob; - const uint8_t fsp_hob_iio_universal_data_guid[16] = FSP_HOB_IIO_UNIVERSAL_DATA_GUID; - - hob = fsp_find_extension_hob_by_guid(fsp_hob_iio_universal_data_guid, &hob_size); - assert(hob != NULL && hob_size != 0); - return hob; -} - -unsigned int soc_get_num_cpus(void) -{ - /* The FSP IIO UDS HOB has field numCpus, it is actually socket count */ - return get_iio_uds()->SystemStatus.numCpus; -} - -void xeonsp_init_cpu_config(void) -{ - struct device *dev; - int apic_ids[CONFIG_MAX_CPUS] = {0}, apic_ids_by_thread[CONFIG_MAX_CPUS] = {0}; - int num_apics = 0; - uint32_t core_bits, thread_bits; - unsigned int core_count, thread_count; - unsigned int num_sockets; - - /* - * sort APIC ids in asending order to identify apicid ranges for - * each numa domain - */ - for (dev = all_devices; dev; dev = dev->next) { - if ((dev->path.type != DEVICE_PATH_APIC) || - (dev->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { - continue; - } - if (!dev->enabled) - continue; - if (num_apics >= ARRAY_SIZE(apic_ids)) - break; - apic_ids[num_apics++] = dev->path.apic.apic_id; - } - if (num_apics > 1) - bubblesort(apic_ids, num_apics, NUM_ASCENDING); - - num_sockets = soc_get_num_cpus(); - cpu_read_topology(&core_count, &thread_count); - assert(num_apics == (num_sockets * thread_count)); - - /* sort them by thread i.e., all cores with thread 0 and then thread 1 */ - int index = 0; - for (int id = 0; id < num_apics; ++id) { - int apic_id = apic_ids[id]; - if (apic_id & 0x1) { /* 2nd thread */ - apic_ids_by_thread[index + (num_apics/2) - 1] = apic_id; - } else { /* 1st thread */ - apic_ids_by_thread[index++] = apic_id; - } - } - - /* update apic_id, node_id in sorted order */ - num_apics = 0; - get_core_thread_bits(&core_bits, &thread_bits); - for (dev = all_devices; dev; dev = dev->next) { - uint8_t package; - - if ((dev->path.type != DEVICE_PATH_APIC) || - (dev->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { - continue; - } - if (!dev->enabled) - continue; - if (num_apics >= ARRAY_SIZE(apic_ids)) - break; - dev->path.apic.apic_id = apic_ids_by_thread[num_apics]; - get_cpu_info_from_apicid(dev->path.apic.apic_id, core_bits, thread_bits, - &package, NULL, NULL); - dev->path.apic.node_id = package; - printk(BIOS_DEBUG, "CPU %d apic_id: 0x%x (%d), node_id: 0x%x\n", - num_apics, dev->path.apic.apic_id, - dev->path.apic.apic_id, dev->path.apic.node_id); - - ++num_apics; - } -} - uint8_t get_iiostack_info(struct iiostack_resource *info) { size_t hob_size; diff --git a/src/soc/intel/xeon_sp/include/soc/util.h b/src/soc/intel/xeon_sp/include/soc/util.h index 51e2b69..73fc63d 100644 --- a/src/soc/intel/xeon_sp/include/soc/util.h +++ b/src/soc/intel/xeon_sp/include/soc/util.h @@ -10,5 +10,10 @@ void unlock_pam_regions(void); void get_stack_busnos(uint32_t *bus); msr_t read_msr_ppin(void); +int get_threads_per_package(void); +int get_platform_thread_count(void); +const IIO_UDS *get_iio_uds(void); +unsigned int soc_get_num_cpus(void); +void xeonsp_init_cpu_config(void);
#endif diff --git a/src/soc/intel/xeon_sp/nb_acpi.c b/src/soc/intel/xeon_sp/nb_acpi.c index f6bf6ed..c48fb92 100644 --- a/src/soc/intel/xeon_sp/nb_acpi.c +++ b/src/soc/intel/xeon_sp/nb_acpi.c @@ -11,6 +11,7 @@ #include <soc/iomap.h> #include <soc/pci_devs.h> #include <soc/soc_util.h> +#include <soc/util.h>
#include "chip.h"
diff --git a/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h b/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h index cce542a..fd0d4e2 100644 --- a/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h +++ b/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h @@ -13,20 +13,11 @@
uint8_t get_iiostack_info(struct iiostack_resource *info);
-void xeonsp_init_cpu_config(void); - void config_reset_cpl3_csrs(void);
-void get_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits); -void get_cpu_info_from_apicid(uint32_t apicid, uint32_t core_bits, uint32_t thread_bits, - uint8_t *package, uint8_t *core, uint8_t *thread); - -int get_platform_thread_count(void); -int get_threads_per_package(void); const struct SystemMemoryMapHob *get_system_memory_map(void);
void set_bios_init_completion(void); -unsigned int soc_get_num_cpus(void); int soc_get_stack_for_port(int port);
#endif /* _SOC_UTIL_H_ */ diff --git a/src/soc/intel/xeon_sp/skx/soc_util.c b/src/soc/intel/xeon_sp/skx/soc_util.c index 3af6483..5a2b3c6 100644 --- a/src/soc/intel/xeon_sp/skx/soc_util.c +++ b/src/soc/intel/xeon_sp/skx/soc_util.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */
#include <assert.h> -#include <commonlib/sort.h> #include <console/console.h> #include <delay.h> #include <device/pci.h> @@ -230,64 +229,6 @@ set_bios_init_completion_for_package(sbsp_socket_id); }
-void get_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits) -{ - register int ecx; - struct cpuid_result cpuid_regs; - - /* get max index of CPUID */ - cpuid_regs = cpuid(0); - assert(cpuid_regs.eax >= 0xb); /* cpuid_regs.eax is max input value for cpuid */ - - *thread_bits = *core_bits = 0; - ecx = 0; - while (1) { - cpuid_regs = cpuid_ext(0xb, ecx); - if (ecx == 0) { - *thread_bits = (cpuid_regs.eax & 0x1f); - } else { - *core_bits = (cpuid_regs.eax & 0x1f) - *thread_bits; - break; - } - ecx++; - } -} - -void get_cpu_info_from_apicid(uint32_t apicid, uint32_t core_bits, uint32_t thread_bits, - uint8_t *package, uint8_t *core, uint8_t *thread) -{ - if (package != NULL) - *package = (apicid >> (thread_bits + core_bits)); - if (core != NULL) - *core = (uint32_t)((apicid >> thread_bits) & ~((~0) << core_bits)); - if (thread != NULL) - *thread = (uint32_t)(apicid & ~((~0) << thread_bits)); -} - -unsigned int soc_get_num_cpus(void) -{ - size_t hob_size; - const uint8_t fsp_hob_iio_universal_data_guid[16] = FSP_HOB_IIO_UNIVERSAL_DATA_GUID; - const IIO_UDS *hob; - - /* these fields are incorrect - need debugging */ - hob = fsp_find_extension_hob_by_guid(fsp_hob_iio_universal_data_guid, &hob_size); - assert(hob != NULL && hob_size != 0); - return hob->SystemStatus.numCpus; -} - -int get_threads_per_package(void) -{ - unsigned int core_count, thread_count; - cpu_read_topology(&core_count, &thread_count); - return thread_count; -} - -int get_platform_thread_count(void) -{ - return soc_get_num_cpus() * get_threads_per_package(); -} - uint8_t get_iiostack_info(struct iiostack_resource *info) { size_t hob_size; @@ -327,73 +268,6 @@ return memmap_addr; }
-void xeonsp_init_cpu_config(void) -{ - struct device *dev; - int apic_ids[CONFIG_MAX_CPUS] = {0}, apic_ids_by_thread[CONFIG_MAX_CPUS] = {0}; - int num_apics = 0; - uint32_t core_bits, thread_bits; - unsigned int core_count, thread_count; - unsigned int num_cpus; - - /* sort APIC ids in asending order to identify apicid ranges for - each numa domain - */ - for (dev = all_devices; dev; dev = dev->next) { - if ((dev->path.type != DEVICE_PATH_APIC) || - (dev->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { - continue; - } - if (!dev->enabled) - continue; - if (num_apics >= ARRAY_SIZE(apic_ids)) - break; - apic_ids[num_apics++] = dev->path.apic.apic_id; - } - if (num_apics > 1) - bubblesort(apic_ids, num_apics, NUM_ASCENDING); - - num_cpus = soc_get_num_cpus(); - cpu_read_topology(&core_count, &thread_count); - assert(num_apics == (num_cpus * thread_count)); - - /* sort them by thread i.e., all cores with thread 0 and then thread 1 */ - int index = 0; - for (int id = 0; id < num_apics; ++id) { - int apic_id = apic_ids[id]; - if (apic_id & 0x1) { /* 2nd thread */ - apic_ids_by_thread[index + (num_apics/2) - 1] = apic_id; - } else { /* 1st thread */ - apic_ids_by_thread[index++] = apic_id; - } - } - - /* update apic_id, node_id in sorted order */ - num_apics = 0; - get_core_thread_bits(&core_bits, &thread_bits); - for (dev = all_devices; dev; dev = dev->next) { - uint8_t package; - - if ((dev->path.type != DEVICE_PATH_APIC) || - (dev->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { - continue; - } - if (!dev->enabled) - continue; - if (num_apics >= ARRAY_SIZE(apic_ids)) - break; - dev->path.apic.apic_id = apic_ids_by_thread[num_apics]; - get_cpu_info_from_apicid(dev->path.apic.apic_id, core_bits, thread_bits, - &package, NULL, NULL); - dev->path.apic.node_id = package; - printk(BIOS_DEBUG, "CPU %d apic_id: 0x%x (%d), node_id: 0x%x\n", - num_apics, dev->path.apic.apic_id, - dev->path.apic.apic_id, dev->path.apic.node_id); - - ++num_apics; - } -} - /* * EX: SKX-SP * Ports Stack Stack(HOB) IioConfigIou diff --git a/src/soc/intel/xeon_sp/util.c b/src/soc/intel/xeon_sp/util.c index 66b9ef1..feacca4 100644 --- a/src/soc/intel/xeon_sp/util.c +++ b/src/soc/intel/xeon_sp/util.c @@ -1,7 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <assert.h> +#include <commonlib/sort.h> #include <console/console.h> +#include <device/device.h> #include <device/pci.h> +#include <intelblocks/cpulib.h> #include <soc/pci_devs.h> #include <soc/msr.h> #include <soc/util.h> @@ -85,3 +89,136 @@ wrmsr(MSR_PPIN_CTL, msr); return ppin; } + +int get_threads_per_package(void) +{ + unsigned int core_count, thread_count; + cpu_read_topology(&core_count, &thread_count); + return thread_count; +} + +int get_platform_thread_count(void) +{ + return soc_get_num_cpus() * get_threads_per_package(); +} + +const IIO_UDS *get_iio_uds(void) +{ + size_t hob_size; + const IIO_UDS *hob; + const uint8_t fsp_hob_iio_universal_data_guid[16] = FSP_HOB_IIO_UNIVERSAL_DATA_GUID; + + hob = fsp_find_extension_hob_by_guid(fsp_hob_iio_universal_data_guid, &hob_size); + assert(hob != NULL && hob_size != 0); + return hob; +} + +unsigned int soc_get_num_cpus(void) +{ + /* The FSP IIO UDS HOB has field numCpus, it is actually socket count */ + return get_iio_uds()->SystemStatus.numCpus; +} + +#if ENV_RAMSTAGE /* Setting devtree variables is only allowed in ramstage. */ +static void get_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits) +{ + register int ecx; + struct cpuid_result cpuid_regs; + + /* get max index of CPUID */ + cpuid_regs = cpuid(0); + assert(cpuid_regs.eax >= 0xb); /* cpuid_regs.eax is max input value for cpuid */ + + *thread_bits = *core_bits = 0; + ecx = 0; + while (1) { + cpuid_regs = cpuid_ext(0xb, ecx); + if (ecx == 0) { + *thread_bits = (cpuid_regs.eax & 0x1f); + } else { + *core_bits = (cpuid_regs.eax & 0x1f) - *thread_bits; + break; + } + ecx++; + } +} + +static void get_cpu_info_from_apicid(uint32_t apicid, uint32_t core_bits, uint32_t thread_bits, + uint8_t *package, uint8_t *core, uint8_t *thread) +{ + if (package != NULL) + *package = (apicid >> (thread_bits + core_bits)); + if (core != NULL) + *core = (uint32_t)((apicid >> thread_bits) & ~((~0) << core_bits)); + if (thread != NULL) + *thread = (uint32_t)(apicid & ~((~0) << thread_bits)); +} + +void xeonsp_init_cpu_config(void) +{ + struct device *dev; + int apic_ids[CONFIG_MAX_CPUS] = {0}, apic_ids_by_thread[CONFIG_MAX_CPUS] = {0}; + int num_apics = 0; + uint32_t core_bits, thread_bits; + unsigned int core_count, thread_count; + unsigned int num_sockets; + + /* + * sort APIC ids in asending order to identify apicid ranges for + * each numa domain + */ + for (dev = all_devices; dev; dev = dev->next) { + if ((dev->path.type != DEVICE_PATH_APIC) || + (dev->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { + continue; + } + if (!dev->enabled) + continue; + if (num_apics >= ARRAY_SIZE(apic_ids)) + break; + apic_ids[num_apics++] = dev->path.apic.apic_id; + } + if (num_apics > 1) + bubblesort(apic_ids, num_apics, NUM_ASCENDING); + + num_sockets = soc_get_num_cpus(); + cpu_read_topology(&core_count, &thread_count); + assert(num_apics == (num_sockets * thread_count)); + + /* sort them by thread i.e., all cores with thread 0 and then thread 1 */ + int index = 0; + for (int id = 0; id < num_apics; ++id) { + int apic_id = apic_ids[id]; + if (apic_id & 0x1) { /* 2nd thread */ + apic_ids_by_thread[index + (num_apics/2) - 1] = apic_id; + } else { /* 1st thread */ + apic_ids_by_thread[index++] = apic_id; + } + } + + /* update apic_id, node_id in sorted order */ + num_apics = 0; + get_core_thread_bits(&core_bits, &thread_bits); + for (dev = all_devices; dev; dev = dev->next) { + uint8_t package; + + if ((dev->path.type != DEVICE_PATH_APIC) || + (dev->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { + continue; + } + if (!dev->enabled) + continue; + if (num_apics >= ARRAY_SIZE(apic_ids)) + break; + dev->path.apic.apic_id = apic_ids_by_thread[num_apics]; + get_cpu_info_from_apicid(dev->path.apic.apic_id, core_bits, thread_bits, + &package, NULL, NULL); + dev->path.apic.node_id = package; + printk(BIOS_DEBUG, "CPU %d apic_id: 0x%x (%d), node_id: 0x%x\n", + num_apics, dev->path.apic.apic_id, + dev->path.apic.apic_id, dev->path.apic.node_id); + + ++num_apics; + } +} +#endif