coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mp_service_ppi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <cpu/cpu.h>
5 #include <cpu/x86/mp.h>
6 #include <cpu/intel/microcode.h>
7 #include <fsp/api.h>
9 #include <intelblocks/cpulib.h>
10 #include <intelblocks/mp_init.h>
11 #include <types.h>
12 
13 #define BSP_CPU_SLOT 0
14 
16  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 
29  efi_processor_information *processor_info_buffer)
30 {
31  int apicid;
32  uint8_t package, core, thread;
33 
34  if (cpu_index() < 0)
35  return FSP_DEVICE_ERROR;
36 
37  if (processor_info_buffer == NULL)
38  return FSP_INVALID_PARAMETER;
39 
40  if (processor_number >= get_cpu_count())
41  return FSP_NOT_FOUND;
42 
43  apicid = cpu_get_apic_id(processor_number);
44 
45  if (apicid < 0)
46  return FSP_DEVICE_ERROR;
47 
48  processor_info_buffer->ProcessorId = apicid;
49 
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 
56  /* Fill EFI_CPU_PHYSICAL_LOCATION structure information */
57  get_cpu_topology_from_apicid(apicid, &package, &core, &thread);
58 
59  processor_info_buffer->Location.Package = package;
60  processor_info_buffer->Location.Core = core;
61  processor_info_buffer->Location.Thread = thread;
62 
63  return FSP_SUCCESS;
64 }
65 
67  bool run_serial, efi_uintn_t timeout_usec, void *argument)
68 {
69  if (cpu_index() < 0)
70  return FSP_DEVICE_ERROR;
71 
72  if (procedure == NULL)
73  return FSP_INVALID_PARAMETER;
74 
75  if (mp_run_on_all_aps((void *)procedure, argument, timeout_usec, !run_serial) !=
76  CB_SUCCESS) {
77  printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
78  return FSP_NOT_STARTED;
79  }
80 
81  return FSP_SUCCESS;
82 }
83 
85  efi_uintn_t timeout_usec, void *argument)
86 {
87  if (cpu_index() < 0)
88  return FSP_DEVICE_ERROR;
89 
90  if (procedure == NULL)
91  return FSP_INVALID_PARAMETER;
92 
93  /* Run on BSP */
94  procedure(argument);
95 
96  /*
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__);
113  return FSP_NOT_STARTED;
114  }
115 
116  return FSP_SUCCESS;
117 }
118 
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 
125  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,
135  processor_number, timeout_usec) != CB_SUCCESS) {
136  printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
137  return FSP_NOT_STARTED;
138  }
139 
140  return FSP_SUCCESS;
141 }
142 
144 {
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 }
int cpu_get_apic_id(int logical_cpu)
Definition: cpu.c:223
int cpu_index(void)
Definition: cpu.c:332
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
#define printk(level,...)
Definition: stdlib.h:16
enum cb_err mp_run_on_all_aps(void(*func)(void *), void *arg, long expire_us, bool run_parallel)
Definition: mp_init.c:979
enum cb_err mp_run_on_aps(void(*func)(void *), void *arg, int logical_cpu_num, long expire_us)
Definition: mp_init.c:971
void get_cpu_topology_from_apicid(uint32_t apicid, uint8_t *package, uint8_t *core, uint8_t *thread)
Definition: cpulib.c:471
void(EFIAPI * efi_ap_procedure)(void *buffer)
Definition: efi_datatype.h:69
UINTN efi_uintn_t
Definition: efi_datatype.h:53
EFI_STATUS efi_return_status_t
Definition: efi_datatype.h:57
EFI_PROCESSOR_INFORMATION efi_processor_information
Definition: efi_datatype.h:18
#define FSP_SUCCESS
Definition: api.h:11
#define FSP_INVALID_PARAMETER
Definition: api.h:12
#define FSP_NOT_STARTED
Definition: api.h:15
#define FSP_NOT_FOUND
Definition: api.h:14
#define FSP_DEVICE_ERROR
Definition: api.h:13
static int get_cpu_count(void)
Definition: haswell_init.c:584
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
efi_return_status_t mp_get_number_of_processors(efi_uintn_t *number_of_processors, efi_uintn_t *number_of_enabled_processors)
efi_return_status_t mp_get_processor_info(efi_uintn_t processor_number, efi_processor_information *processor_info_buffer)
efi_return_status_t mp_identify_processor(efi_uintn_t *processor_number)
efi_return_status_t mp_startup_all_cpus(efi_ap_procedure procedure, efi_uintn_t timeout_usec, void *argument)
#define BSP_CPU_SLOT
efi_return_status_t mp_startup_all_aps(efi_ap_procedure procedure, bool run_serial, efi_uintn_t timeout_usec, void *argument)
efi_return_status_t mp_startup_this_ap(efi_ap_procedure procedure, efi_uintn_t processor_number, efi_uintn_t timeout_usec, void *argument)
#define NULL
Definition: stddef.h:19
unsigned char uint8_t
Definition: stdint.h:8