blob: 53d91822b87d277d6110c25fcd960d9c9bc2ddd0 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Subrata Banik6662cb32018-04-12 19:25:37 +05302
Elyes HAOUAS20eaef02019-03-29 17:45:28 +01003#include <console/console.h>
Aamir Bohra01ae4a72021-02-19 16:35:09 +05304#include <cpu/cpu.h>
Subrata Banik6662cb32018-04-12 19:25:37 +05305#include <cpu/x86/mp.h>
Subrata Banik6662cb32018-04-12 19:25:37 +05306#include <cpu/intel/microcode.h>
7#include <fsp/api.h>
8#include <fsp/ppi/mp_service_ppi.h>
9#include <intelblocks/cpulib.h>
10#include <intelblocks/mp_init.h>
Felix Held82faefb2021-10-20 20:50:58 +020011#include <types.h>
Subrata Banik6662cb32018-04-12 19:25:37 +053012
13#define BSP_CPU_SLOT 0
14
Aamir Bohra30cca6c2021-02-04 20:57:51 +053015efi_return_status_t mp_get_number_of_processors(efi_uintn_t *number_of_processors,
Subrata Banik6662cb32018-04-12 19:25:37 +053016 efi_uintn_t *number_of_enabled_processors)
17{
18 if (number_of_processors == NULL || number_of_enabled_processors ==
19 NULL)
20 return FSP_INVALID_PARAMETER;
21
22 *number_of_processors = get_cpu_count();
23 *number_of_enabled_processors = get_cpu_count();
24
25 return FSP_SUCCESS;
26}
27
Aamir Bohra30cca6c2021-02-04 20:57:51 +053028efi_return_status_t mp_get_processor_info(efi_uintn_t processor_number,
Subrata Banik6662cb32018-04-12 19:25:37 +053029 efi_processor_information *processor_info_buffer)
30{
Aamir Bohra01ae4a72021-02-19 16:35:09 +053031 int apicid;
32 uint8_t package, core, thread;
Subrata Banikef04f4e2020-08-11 18:13:04 +053033
Jacob Garberbc674762019-05-14 11:21:41 -060034 if (cpu_index() < 0)
35 return FSP_DEVICE_ERROR;
36
Subrata Banik6662cb32018-04-12 19:25:37 +053037 if (processor_info_buffer == NULL)
38 return FSP_INVALID_PARAMETER;
39
40 if (processor_number >= get_cpu_count())
41 return FSP_NOT_FOUND;
42
Aamir Bohra01ae4a72021-02-19 16:35:09 +053043 apicid = cpu_get_apic_id(processor_number);
44
45 if (apicid < 0)
46 return FSP_DEVICE_ERROR;
47
48 processor_info_buffer->ProcessorId = apicid;
Subrata Banik6662cb32018-04-12 19:25:37 +053049
50 processor_info_buffer->StatusFlag = PROCESSOR_HEALTH_STATUS_BIT
51 | PROCESSOR_ENABLED_BIT;
52
53 if (processor_number == BSP_CPU_SLOT)
54 processor_info_buffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
55
Subrata Banikef04f4e2020-08-11 18:13:04 +053056 /* Fill EFI_CPU_PHYSICAL_LOCATION structure information */
Aamir Bohra01ae4a72021-02-19 16:35:09 +053057 get_cpu_topology_from_apicid(apicid, &package, &core, &thread);
Subrata Banikef04f4e2020-08-11 18:13:04 +053058
Aamir Bohra01ae4a72021-02-19 16:35:09 +053059 processor_info_buffer->Location.Package = package;
60 processor_info_buffer->Location.Core = core;
61 processor_info_buffer->Location.Thread = thread;
Subrata Banikef04f4e2020-08-11 18:13:04 +053062
Subrata Banik6662cb32018-04-12 19:25:37 +053063 return FSP_SUCCESS;
64}
65
Aamir Bohra30cca6c2021-02-04 20:57:51 +053066efi_return_status_t mp_startup_all_aps(efi_ap_procedure procedure,
Aamir Bohra813a3ba2021-02-25 13:25:57 +053067 bool run_serial, efi_uintn_t timeout_usec, void *argument)
Subrata Banik6662cb32018-04-12 19:25:37 +053068{
Jacob Garberbc674762019-05-14 11:21:41 -060069 if (cpu_index() < 0)
70 return FSP_DEVICE_ERROR;
71
Subrata Banik6662cb32018-04-12 19:25:37 +053072 if (procedure == NULL)
73 return FSP_INVALID_PARAMETER;
74
Felix Held82faefb2021-10-20 20:50:58 +020075 if (mp_run_on_all_aps((void *)procedure, argument, timeout_usec, !run_serial) !=
76 CB_SUCCESS) {
Subrata Banik6662cb32018-04-12 19:25:37 +053077 printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
78 return FSP_NOT_STARTED;
79 }
80
81 return FSP_SUCCESS;
82}
83
Aamir Bohra30cca6c2021-02-04 20:57:51 +053084efi_return_status_t mp_startup_all_cpus(efi_ap_procedure procedure,
Subrata Banik6662cb32018-04-12 19:25:37 +053085 efi_uintn_t timeout_usec, void *argument)
86{
Jacob Garberbc674762019-05-14 11:21:41 -060087 if (cpu_index() < 0)
88 return FSP_DEVICE_ERROR;
89
Aamir Bohra30cca6c2021-02-04 20:57:51 +053090 if (procedure == NULL)
91 return FSP_INVALID_PARAMETER;
92
93 /* Run on BSP */
94 procedure(argument);
95
Nick Vaccaro1abbb962022-03-17 13:06:49 -070096 /*
97 * Run on APs Serially
98 *
99 * FIXME: As per MP service specification, EDK2 is allowed to specify the mode
100 * in which a 'func' routine should be executed on APs (i.e. execute serially
101 * or concurrently).
102 *
103 * MP service API `StartupAllCPUs` doesn't specify such requirement.
104 * Hence, running the `CpuCacheInfoCollectCoreAndCacheData`
105 * (UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c#194)
106 * simultaneously on APs results in a coherency issue (hang while executing `func`)
107 * due to lack of acquiring a spin lock while accessing common data structure in
108 * multiprocessor environment.
109 */
110 if (mp_run_on_all_aps((void *)procedure, argument, timeout_usec, false) !=
111 CB_SUCCESS) {
112 printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
Aamir Bohra30cca6c2021-02-04 20:57:51 +0530113 return FSP_NOT_STARTED;
114 }
115
116 return FSP_SUCCESS;
117}
118
119efi_return_status_t mp_startup_this_ap(efi_ap_procedure procedure,
120 efi_uintn_t processor_number, efi_uintn_t timeout_usec, void *argument)
121{
122 if (cpu_index() < 0)
123 return FSP_DEVICE_ERROR;
124
Subrata Banik6662cb32018-04-12 19:25:37 +0530125 if (processor_number > get_cpu_count())
126 return FSP_NOT_FOUND;
127
128 if (processor_number == BSP_CPU_SLOT)
129 return FSP_INVALID_PARAMETER;
130
131 if (procedure == NULL)
132 return FSP_INVALID_PARAMETER;
133
134 if (mp_run_on_aps((void *)procedure, argument,
Felix Held82faefb2021-10-20 20:50:58 +0200135 processor_number, timeout_usec) != CB_SUCCESS) {
Subrata Banik6662cb32018-04-12 19:25:37 +0530136 printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
137 return FSP_NOT_STARTED;
138 }
139
140 return FSP_SUCCESS;
141}
142
Aamir Bohra30cca6c2021-02-04 20:57:51 +0530143efi_return_status_t mp_identify_processor(efi_uintn_t *processor_number)
Subrata Banik6662cb32018-04-12 19:25:37 +0530144{
145 int index;
146
147 if (processor_number == NULL)
148 return FSP_INVALID_PARAMETER;
149
150 index = cpu_index();
151
152 if (index < 0)
153 return FSP_DEVICE_ERROR;
154
155 *processor_number = index;
156
157 return FSP_SUCCESS;
158}