iPXE
mp.h
Go to the documentation of this file.
1 #ifndef _IPXE_MP_H
2 #define _IPXE_MP_H
3 
4 /** @file
5  *
6  * Multiprocessor functions
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <ipxe/api.h>
14 #include <config/defaults.h>
15 
16 /**
17  * An address within the address space for a multiprocessor function
18  *
19  * Application processors may be started in a different address space
20  * from the normal iPXE runtime environment. For example: under
21  * legacy BIOS the application processors will use flat 32-bit
22  * physical addressing (with no paging or virtual address offset).
23  */
24 typedef unsigned long mp_addr_t;
25 
26 /** A multiprocessor function
27  *
28  * @v opaque Opaque data pointer
29  * @v cpuid CPU identifier
30  *
31  * iPXE does not set up a normal multiprocessor environment. In
32  * particular, there is no support for dispatching code to individual
33  * processors and there is no per-CPU stack allocation.
34  *
35  * Multiprocessor code must be prepared to run wth no stack space (and
36  * with a zero stack pointer). Functions may use the CPU identifier
37  * to construct a pointer to per-CPU result storage.
38  *
39  * Multiprocessor functions are permitted to overwrite all registers
40  * apart from the stack pointer. On exit, the function should check
41  * the stack pointer value: if zero then the function should halt the
42  * CPU, if non-zero then the function should return in the normal way.
43  *
44  * Multiprocessor functions do not have access to any capabilities
45  * typically provided by the firmware: they cannot, for example, write
46  * any console output.
47  *
48  * All parameters are passed in registers, since there may be no stack
49  * available. These functions cannot be called directly from C code.
50  */
51 typedef void ( mp_func_t ) ( mp_addr_t opaque, unsigned int cpuid );
52 
53 /**
54  * Call a multiprocessor function from C code on the current CPU
55  *
56  * @v func Multiprocessor function
57  * @v opaque Opaque data pointer
58  *
59  * This function must be provided for each CPU architecture to bridge
60  * the normal C ABI to the iPXE multiprocessor function ABI. It must
61  * therefore preserve any necessary registers, determine the CPU
62  * identifier, call the multiprocessor function (which may destroy any
63  * registers other than the stack pointer), restore registers, and
64  * return to the C caller.
65  *
66  * This function must be called from within the multiprocessor address
67  * space (e.g. with flat 32-bit physical addressing for BIOS). It can
68  * be called directly from C code if the multiprocessor address space
69  * is identical to the address space used for C code (e.g. under EFI,
70  * where everything uses flat physical addresses).
71  */
72 extern void __asmcall mp_call ( mp_addr_t func, mp_addr_t opaque );
73 
74 /**
75  * Calculate static inline multiprocessor API function name
76  *
77  * @v _prefix Subsystem prefix
78  * @v _api_func API function
79  * @ret _subsys_func Subsystem API function
80  */
81 #define MPAPI_INLINE( _subsys, _api_func ) \
82  SINGLE_API_INLINE ( MPAPI_PREFIX_ ## _subsys, _api_func )
83 
84 /**
85  * Provide a multiprocessor API implementation
86  *
87  * @v _prefix Subsystem prefix
88  * @v _api_func API function
89  * @v _func Implementing function
90  */
91 #define PROVIDE_MPAPI( _subsys, _api_func, _func ) \
92  PROVIDE_SINGLE_API ( MPAPI_PREFIX_ ## _subsys, _api_func, _func )
93 
94 /**
95  * Provide a static inline multiprocessor API implementation
96  *
97  * @v _prefix Subsystem prefix
98  * @v _api_func API function
99  */
100 #define PROVIDE_MPAPI_INLINE( _subsys, _api_func ) \
101  PROVIDE_SINGLE_API_INLINE ( MPAPI_PREFIX_ ## _subsys, _api_func )
102 
103 /* Include all architecture-independent multiprocessor API headers */
104 #include <ipxe/null_mp.h>
105 #include <ipxe/efi/efi_mp.h>
106 
107 /* Include all architecture-dependent multiprocessor API headers */
108 #include <bits/mp.h>
109 
110 /**
111  * Calculate address as seen by a multiprocessor function
112  *
113  * @v address Address in normal iPXE address space
114  * @ret address Address in application processor address space
115  */
116 mp_addr_t mp_address ( void *address );
117 
118 /**
119  * Execute a multiprocessor function on the boot processor
120  *
121  * @v func Multiprocessor function
122  * @v opaque Opaque data pointer
123  *
124  * This is a blocking operation: the call will return only when the
125  * multiprocessor function exits.
126  */
127 void mp_exec_boot ( mp_func_t func, void *opaque );
128 
129 /**
130  * Start a multiprocessor function on all application processors
131  *
132  * @v func Multiprocessor function
133  * @v opaque Opaque data pointer
134  *
135  * This is a non-blocking operation: it is the caller's responsibility
136  * to provide a way to determine when the multiprocessor function has
137  * finished executing and halted its CPU.
138  */
139 void mp_start_all ( mp_func_t func, void *opaque );
140 
141 /**
142  * Update maximum observed CPU identifier
143  *
144  * @v opaque Opaque data pointer
145  * @v cpuid CPU identifier
146  *
147  * This may be invoked on each processor to update a shared maximum
148  * CPU identifier value.
149  */
151 
152 extern unsigned int mp_boot_cpuid ( void );
153 extern unsigned int mp_max_cpuid ( void );
154 
155 #endif /* _IPXE_MP_H */
mp_addr_t mp_address(void *address)
Calculate address as seen by a multiprocessor function.
Definition: efi_mp.h:25
iPXE internal APIs
uint64_t address
Base address.
Definition: ena.h:24
unsigned int mp_boot_cpuid(void)
Get boot CPU identifier.
Definition: mp.c:43
void mp_start_all(mp_func_t func, void *opaque)
Start a multiprocessor function on all application processors.
void __asmcall mp_call(mp_addr_t func, mp_addr_t opaque)
Call a multiprocessor function from C code on the current CPU.
mp_func_t mp_update_max_cpuid
Update maximum observed CPU identifier.
#define __asmcall
Declare a function with standard calling conventions.
Definition: compiler.h:15
void() mp_func_t(mp_addr_t opaque, unsigned int cpuid)
A multiprocessor function.
Definition: mp.h:51
unsigned long mp_addr_t
An address within the address space for a multiprocessor function.
Definition: mp.h:24
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
x86-specific multiprocessor API implementation
Null multiprocessor API implementation.
EFI multiprocessor API implementation.
unsigned int mp_max_cpuid(void)
Get maximum CPU identifier.
Definition: mp.c:58
void mp_exec_boot(mp_func_t func, void *opaque)
Execute a multiprocessor function on the boot processor.