summaryrefslogtreecommitdiffstats
path: root/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c
blob: fead4f1a98c887b1cb97630c01b2bab6f2aca5d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* SPDX-License-Identifier: GPL-2.0-only */
/* This file is part of the coreboot project. */

#include <console/console.h>
#include <cpu/x86/mp.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <fsp/api.h>
#include <fsp/ppi/mp_service_ppi.h>
#include <intelblocks/cpulib.h>
#include <intelblocks/mp_init.h>

#define BSP_CPU_SLOT 0

static efi_return_status_t mp_get_number_of_processors(const
	efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
	efi_uintn_t *number_of_processors,
	efi_uintn_t *number_of_enabled_processors)
{
	if (number_of_processors == NULL || number_of_enabled_processors ==
			NULL)
		return FSP_INVALID_PARAMETER;

	*number_of_processors = get_cpu_count();
	*number_of_enabled_processors = get_cpu_count();

	return FSP_SUCCESS;
}

static efi_return_status_t mp_get_processor_info(const
	efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
	efi_uintn_t processor_number,
	efi_processor_information *processor_info_buffer)
{
	if (cpu_index() < 0)
		return FSP_DEVICE_ERROR;

	if (processor_info_buffer == NULL)
		return FSP_INVALID_PARAMETER;

	if (processor_number >= get_cpu_count())
		return FSP_NOT_FOUND;

	processor_info_buffer->ProcessorId = lapicid();

	processor_info_buffer->StatusFlag = PROCESSOR_HEALTH_STATUS_BIT
			| PROCESSOR_ENABLED_BIT;

	if (processor_number == BSP_CPU_SLOT)
		processor_info_buffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;

	/* TODO: Fill EFI_CPU_PHYSICAL_LOCATION structure information */
	return FSP_SUCCESS;
}

static efi_return_status_t mp_startup_all_aps(const
	efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
	efi_ap_procedure procedure, efi_boolean_t ignored3,
	efi_uintn_t timeout_usec, void *argument)
{
	if (cpu_index() < 0)
		return FSP_DEVICE_ERROR;

	if (procedure == NULL)
		return FSP_INVALID_PARAMETER;

	if (mp_run_on_aps((void *)procedure, argument,
			MP_RUN_ON_ALL_CPUS, timeout_usec)) {
		printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
		return FSP_NOT_STARTED;
	}

	return FSP_SUCCESS;
}

static efi_return_status_t mp_startup_this_ap(const
	efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
	efi_ap_procedure procedure, efi_uintn_t processor_number,
	efi_uintn_t timeout_usec, void *argument)
{
	if (cpu_index() < 0)
		return FSP_DEVICE_ERROR;

	if (processor_number > get_cpu_count())
		return FSP_NOT_FOUND;

	if (processor_number == BSP_CPU_SLOT)
		return FSP_INVALID_PARAMETER;

	if (procedure == NULL)
		return FSP_INVALID_PARAMETER;

	if (mp_run_on_aps((void *)procedure, argument,
			processor_number, timeout_usec)) {
		printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
		return FSP_NOT_STARTED;
	}

	return FSP_SUCCESS;
}

static efi_return_status_t mp_switch_bsp(const efi_pei_services **ignored1,
	efi_pei_mp_services_ppi *ignored2, efi_uintn_t ignored3,
	efi_boolean_t ignored4)
{
	/* FSP don't need this API hence return unsupported */
	return FSP_UNSUPPORTED;
}

static efi_return_status_t mp_enable_disable_ap(const
	efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
	efi_uintn_t ignored3, efi_boolean_t ignored4, efi_uint32_t *ignored5)
{
	/* FSP don't need this API hence return unsupported */
	return FSP_UNSUPPORTED;
}

static efi_return_status_t mp_identify_processor(const
	efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
	efi_uintn_t *processor_number)
{
	int index;

	if (processor_number == NULL)
		return FSP_INVALID_PARAMETER;

	index = cpu_index();

	if (index < 0)
		return FSP_DEVICE_ERROR;

	*processor_number = index;

	return FSP_SUCCESS;
}

/*
 * EDK2 UEFIPKG Open Source MP Service PPI to be installed
 */

static efi_pei_mp_services_ppi mp_service_ppi = {
	mp_get_number_of_processors,
	mp_get_processor_info,
	mp_startup_all_aps,
	mp_startup_this_ap,
	mp_switch_bsp,
	mp_enable_disable_ap,
	mp_identify_processor,
};

efi_pei_mp_services_ppi *mp_fill_ppi_services_data(void)
{
	return &mp_service_ppi;
}