Angel Pons | 8a3453f | 2020-04-02 23:48:19 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 2 | |
Elyes HAOUAS | 20eaef0 | 2019-03-29 17:45:28 +0100 | [diff] [blame] | 3 | #include <console/console.h> |
Aamir Bohra | 01ae4a7 | 2021-02-19 16:35:09 +0530 | [diff] [blame] | 4 | #include <cpu/cpu.h> |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 5 | #include <cpu/x86/mp.h> |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 6 | #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 Held | 82faefb | 2021-10-20 20:50:58 +0200 | [diff] [blame] | 11 | #include <types.h> |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 12 | |
| 13 | #define BSP_CPU_SLOT 0 |
| 14 | |
Aamir Bohra | 30cca6c | 2021-02-04 20:57:51 +0530 | [diff] [blame] | 15 | efi_return_status_t mp_get_number_of_processors(efi_uintn_t *number_of_processors, |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 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 | |
Aamir Bohra | 30cca6c | 2021-02-04 20:57:51 +0530 | [diff] [blame] | 28 | efi_return_status_t mp_get_processor_info(efi_uintn_t processor_number, |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 29 | efi_processor_information *processor_info_buffer) |
| 30 | { |
Aamir Bohra | 01ae4a7 | 2021-02-19 16:35:09 +0530 | [diff] [blame] | 31 | int apicid; |
| 32 | uint8_t package, core, thread; |
Subrata Banik | ef04f4e | 2020-08-11 18:13:04 +0530 | [diff] [blame] | 33 | |
Jacob Garber | bc67476 | 2019-05-14 11:21:41 -0600 | [diff] [blame] | 34 | if (cpu_index() < 0) |
| 35 | return FSP_DEVICE_ERROR; |
| 36 | |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 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 | |
Aamir Bohra | 01ae4a7 | 2021-02-19 16:35:09 +0530 | [diff] [blame] | 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; |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 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 | |
Subrata Banik | ef04f4e | 2020-08-11 18:13:04 +0530 | [diff] [blame] | 56 | /* Fill EFI_CPU_PHYSICAL_LOCATION structure information */ |
Aamir Bohra | 01ae4a7 | 2021-02-19 16:35:09 +0530 | [diff] [blame] | 57 | get_cpu_topology_from_apicid(apicid, &package, &core, &thread); |
Subrata Banik | ef04f4e | 2020-08-11 18:13:04 +0530 | [diff] [blame] | 58 | |
Aamir Bohra | 01ae4a7 | 2021-02-19 16:35:09 +0530 | [diff] [blame] | 59 | processor_info_buffer->Location.Package = package; |
| 60 | processor_info_buffer->Location.Core = core; |
| 61 | processor_info_buffer->Location.Thread = thread; |
Subrata Banik | ef04f4e | 2020-08-11 18:13:04 +0530 | [diff] [blame] | 62 | |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 63 | return FSP_SUCCESS; |
| 64 | } |
| 65 | |
Aamir Bohra | 30cca6c | 2021-02-04 20:57:51 +0530 | [diff] [blame] | 66 | efi_return_status_t mp_startup_all_aps(efi_ap_procedure procedure, |
Aamir Bohra | 813a3ba | 2021-02-25 13:25:57 +0530 | [diff] [blame] | 67 | bool run_serial, efi_uintn_t timeout_usec, void *argument) |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 68 | { |
Jacob Garber | bc67476 | 2019-05-14 11:21:41 -0600 | [diff] [blame] | 69 | if (cpu_index() < 0) |
| 70 | return FSP_DEVICE_ERROR; |
| 71 | |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 72 | if (procedure == NULL) |
| 73 | return FSP_INVALID_PARAMETER; |
| 74 | |
Felix Held | 82faefb | 2021-10-20 20:50:58 +0200 | [diff] [blame] | 75 | if (mp_run_on_all_aps((void *)procedure, argument, timeout_usec, !run_serial) != |
| 76 | CB_SUCCESS) { |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 77 | printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__); |
| 78 | return FSP_NOT_STARTED; |
| 79 | } |
| 80 | |
| 81 | return FSP_SUCCESS; |
| 82 | } |
| 83 | |
Aamir Bohra | 30cca6c | 2021-02-04 20:57:51 +0530 | [diff] [blame] | 84 | efi_return_status_t mp_startup_all_cpus(efi_ap_procedure procedure, |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 85 | efi_uintn_t timeout_usec, void *argument) |
| 86 | { |
Jacob Garber | bc67476 | 2019-05-14 11:21:41 -0600 | [diff] [blame] | 87 | if (cpu_index() < 0) |
| 88 | return FSP_DEVICE_ERROR; |
| 89 | |
Aamir Bohra | 30cca6c | 2021-02-04 20:57:51 +0530 | [diff] [blame] | 90 | if (procedure == NULL) |
| 91 | return FSP_INVALID_PARAMETER; |
| 92 | |
| 93 | /* Run on BSP */ |
| 94 | procedure(argument); |
| 95 | |
Nick Vaccaro | 1abbb96 | 2022-03-17 13:06:49 -0700 | [diff] [blame] | 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__); |
Aamir Bohra | 30cca6c | 2021-02-04 20:57:51 +0530 | [diff] [blame] | 113 | return FSP_NOT_STARTED; |
| 114 | } |
| 115 | |
| 116 | return FSP_SUCCESS; |
| 117 | } |
| 118 | |
| 119 | efi_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 Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 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, |
Felix Held | 82faefb | 2021-10-20 20:50:58 +0200 | [diff] [blame] | 135 | processor_number, timeout_usec) != CB_SUCCESS) { |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 136 | printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__); |
| 137 | return FSP_NOT_STARTED; |
| 138 | } |
| 139 | |
| 140 | return FSP_SUCCESS; |
| 141 | } |
| 142 | |
Aamir Bohra | 30cca6c | 2021-02-04 20:57:51 +0530 | [diff] [blame] | 143 | efi_return_status_t mp_identify_processor(efi_uintn_t *processor_number) |
Subrata Banik | 6662cb3 | 2018-04-12 19:25:37 +0530 | [diff] [blame] | 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 | } |