]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/Ia32/GccInline.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / GccInline.c
1 /** @file
2 GCC inline implementation of BaseLib processor specific functions.
3
4 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "BaseLibInternals.h"
11
12 /**
13 Used to serialize load and store operations.
14
15 All loads and stores that proceed calls to this function are guaranteed to be
16 globally visible when this function returns.
17
18 **/
19 VOID
20 EFIAPI
21 MemoryFence (
22 VOID
23 )
24 {
25 // This is a little bit of overkill and it is more about the compiler that it is
26 // actually processor synchronization. This is like the _ReadWriteBarrier
27 // Microsoft specific intrinsic
28 __asm__ __volatile__ ("":::"memory");
29 }
30
31 /**
32 Requests CPU to pause for a short period of time.
33
34 Requests CPU to pause for a short period of time. Typically used in MP
35 systems to prevent memory starvation while waiting for a spin lock.
36
37 **/
38 VOID
39 EFIAPI
40 CpuPause (
41 VOID
42 )
43 {
44 __asm__ __volatile__ ("pause");
45 }
46
47 /**
48 Generates a breakpoint on the CPU.
49
50 Generates a breakpoint on the CPU. The breakpoint must be implemented such
51 that code can resume normal execution after the breakpoint.
52
53 **/
54 VOID
55 EFIAPI
56 CpuBreakpoint (
57 VOID
58 )
59 {
60 __asm__ __volatile__ ("int $3");
61 }
62
63 /**
64 Reads the current value of the EFLAGS register.
65
66 Reads and returns the current value of the EFLAGS register. This function is
67 only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
68 64-bit value on X64.
69
70 @return EFLAGS on IA-32 or RFLAGS on X64.
71
72 **/
73 UINTN
74 EFIAPI
75 AsmReadEflags (
76 VOID
77 )
78 {
79 UINTN Eflags;
80
81 __asm__ __volatile__ (
82 "pushfl \n\t"
83 "popl %0 "
84 : "=r" (Eflags)
85 );
86
87 return Eflags;
88 }
89
90 /**
91 Save the current floating point/SSE/SSE2 context to a buffer.
92
93 Saves the current floating point/SSE/SSE2 state to the buffer specified by
94 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
95 available on IA-32 and X64.
96
97 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
98
99 **/
100 VOID
101 EFIAPI
102 InternalX86FxSave (
103 OUT IA32_FX_BUFFER *Buffer
104 )
105 {
106 __asm__ __volatile__ (
107 "fxsave %0"
108 :
109 : "m" (*Buffer) // %0
110 );
111 }
112
113 /**
114 Restores the current floating point/SSE/SSE2 context from a buffer.
115
116 Restores the current floating point/SSE/SSE2 state from the buffer specified
117 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
118 only available on IA-32 and X64.
119
120 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
121
122 **/
123 VOID
124 EFIAPI
125 InternalX86FxRestore (
126 IN CONST IA32_FX_BUFFER *Buffer
127 )
128 {
129 __asm__ __volatile__ (
130 "fxrstor %0"
131 :
132 : "m" (*Buffer) // %0
133 );
134 }
135
136 /**
137 Reads the current value of 64-bit MMX Register #0 (MM0).
138
139 Reads and returns the current value of MM0. This function is only available
140 on IA-32 and X64.
141
142 @return The current value of MM0.
143
144 **/
145 UINT64
146 EFIAPI
147 AsmReadMm0 (
148 VOID
149 )
150 {
151 UINT64 Data;
152
153 __asm__ __volatile__ (
154 "push %%eax \n\t"
155 "push %%eax \n\t"
156 "movq %%mm0, (%%esp)\n\t"
157 "pop %%eax \n\t"
158 "pop %%edx \n\t"
159 : "=A" (Data) // %0
160 );
161
162 return Data;
163 }
164
165 /**
166 Reads the current value of 64-bit MMX Register #1 (MM1).
167
168 Reads and returns the current value of MM1. This function is only available
169 on IA-32 and X64.
170
171 @return The current value of MM1.
172
173 **/
174 UINT64
175 EFIAPI
176 AsmReadMm1 (
177 VOID
178 )
179 {
180 UINT64 Data;
181
182 __asm__ __volatile__ (
183 "push %%eax \n\t"
184 "push %%eax \n\t"
185 "movq %%mm1, (%%esp)\n\t"
186 "pop %%eax \n\t"
187 "pop %%edx \n\t"
188 : "=A" (Data) // %0
189 );
190
191 return Data;
192 }
193
194 /**
195 Reads the current value of 64-bit MMX Register #2 (MM2).
196
197 Reads and returns the current value of MM2. This function is only available
198 on IA-32 and X64.
199
200 @return The current value of MM2.
201
202 **/
203 UINT64
204 EFIAPI
205 AsmReadMm2 (
206 VOID
207 )
208 {
209 UINT64 Data;
210
211 __asm__ __volatile__ (
212 "push %%eax \n\t"
213 "push %%eax \n\t"
214 "movq %%mm2, (%%esp)\n\t"
215 "pop %%eax \n\t"
216 "pop %%edx \n\t"
217 : "=A" (Data) // %0
218 );
219
220 return Data;
221 }
222
223 /**
224 Reads the current value of 64-bit MMX Register #3 (MM3).
225
226 Reads and returns the current value of MM3. This function is only available
227 on IA-32 and X64.
228
229 @return The current value of MM3.
230
231 **/
232 UINT64
233 EFIAPI
234 AsmReadMm3 (
235 VOID
236 )
237 {
238 UINT64 Data;
239
240 __asm__ __volatile__ (
241 "push %%eax \n\t"
242 "push %%eax \n\t"
243 "movq %%mm3, (%%esp)\n\t"
244 "pop %%eax \n\t"
245 "pop %%edx \n\t"
246 : "=A" (Data) // %0
247 );
248
249 return Data;
250 }
251
252 /**
253 Reads the current value of 64-bit MMX Register #4 (MM4).
254
255 Reads and returns the current value of MM4. This function is only available
256 on IA-32 and X64.
257
258 @return The current value of MM4.
259
260 **/
261 UINT64
262 EFIAPI
263 AsmReadMm4 (
264 VOID
265 )
266 {
267 UINT64 Data;
268
269 __asm__ __volatile__ (
270 "push %%eax \n\t"
271 "push %%eax \n\t"
272 "movq %%mm4, (%%esp)\n\t"
273 "pop %%eax \n\t"
274 "pop %%edx \n\t"
275 : "=A" (Data) // %0
276 );
277
278 return Data;
279 }
280
281 /**
282 Reads the current value of 64-bit MMX Register #5 (MM5).
283
284 Reads and returns the current value of MM5. This function is only available
285 on IA-32 and X64.
286
287 @return The current value of MM5.
288
289 **/
290 UINT64
291 EFIAPI
292 AsmReadMm5 (
293 VOID
294 )
295 {
296 UINT64 Data;
297
298 __asm__ __volatile__ (
299 "push %%eax \n\t"
300 "push %%eax \n\t"
301 "movq %%mm5, (%%esp)\n\t"
302 "pop %%eax \n\t"
303 "pop %%edx \n\t"
304 : "=A" (Data) // %0
305 );
306
307 return Data;
308 }
309
310 /**
311 Reads the current value of 64-bit MMX Register #6 (MM6).
312
313 Reads and returns the current value of MM6. This function is only available
314 on IA-32 and X64.
315
316 @return The current value of MM6.
317
318 **/
319 UINT64
320 EFIAPI
321 AsmReadMm6 (
322 VOID
323 )
324 {
325 UINT64 Data;
326
327 __asm__ __volatile__ (
328 "push %%eax \n\t"
329 "push %%eax \n\t"
330 "movq %%mm6, (%%esp)\n\t"
331 "pop %%eax \n\t"
332 "pop %%edx \n\t"
333 : "=A" (Data) // %0
334 );
335
336 return Data;
337 }
338
339 /**
340 Reads the current value of 64-bit MMX Register #7 (MM7).
341
342 Reads and returns the current value of MM7. This function is only available
343 on IA-32 and X64.
344
345 @return The current value of MM7.
346
347 **/
348 UINT64
349 EFIAPI
350 AsmReadMm7 (
351 VOID
352 )
353 {
354 UINT64 Data;
355
356 __asm__ __volatile__ (
357 "push %%eax \n\t"
358 "push %%eax \n\t"
359 "movq %%mm7, (%%esp)\n\t"
360 "pop %%eax \n\t"
361 "pop %%edx \n\t"
362 : "=A" (Data) // %0
363 );
364
365 return Data;
366 }
367
368 /**
369 Writes the current value of 64-bit MMX Register #0 (MM0).
370
371 Writes the current value of MM0. This function is only available on IA32 and
372 X64.
373
374 @param Value The 64-bit value to write to MM0.
375
376 **/
377 VOID
378 EFIAPI
379 AsmWriteMm0 (
380 IN UINT64 Value
381 )
382 {
383 __asm__ __volatile__ (
384 "movq %0, %%mm0" // %0
385 :
386 : "m" (Value)
387 );
388 }
389
390 /**
391 Writes the current value of 64-bit MMX Register #1 (MM1).
392
393 Writes the current value of MM1. This function is only available on IA32 and
394 X64.
395
396 @param Value The 64-bit value to write to MM1.
397
398 **/
399 VOID
400 EFIAPI
401 AsmWriteMm1 (
402 IN UINT64 Value
403 )
404 {
405 __asm__ __volatile__ (
406 "movq %0, %%mm1" // %0
407 :
408 : "m" (Value)
409 );
410 }
411
412 /**
413 Writes the current value of 64-bit MMX Register #2 (MM2).
414
415 Writes the current value of MM2. This function is only available on IA32 and
416 X64.
417
418 @param Value The 64-bit value to write to MM2.
419
420 **/
421 VOID
422 EFIAPI
423 AsmWriteMm2 (
424 IN UINT64 Value
425 )
426 {
427 __asm__ __volatile__ (
428 "movq %0, %%mm2" // %0
429 :
430 : "m" (Value)
431 );
432 }
433
434 /**
435 Writes the current value of 64-bit MMX Register #3 (MM3).
436
437 Writes the current value of MM3. This function is only available on IA32 and
438 X64.
439
440 @param Value The 64-bit value to write to MM3.
441
442 **/
443 VOID
444 EFIAPI
445 AsmWriteMm3 (
446 IN UINT64 Value
447 )
448 {
449 __asm__ __volatile__ (
450 "movq %0, %%mm3" // %0
451 :
452 : "m" (Value)
453 );
454 }
455
456 /**
457 Writes the current value of 64-bit MMX Register #4 (MM4).
458
459 Writes the current value of MM4. This function is only available on IA32 and
460 X64.
461
462 @param Value The 64-bit value to write to MM4.
463
464 **/
465 VOID
466 EFIAPI
467 AsmWriteMm4 (
468 IN UINT64 Value
469 )
470 {
471 __asm__ __volatile__ (
472 "movq %0, %%mm4" // %0
473 :
474 : "m" (Value)
475 );
476 }
477
478 /**
479 Writes the current value of 64-bit MMX Register #5 (MM5).
480
481 Writes the current value of MM5. This function is only available on IA32 and
482 X64.
483
484 @param Value The 64-bit value to write to MM5.
485
486 **/
487 VOID
488 EFIAPI
489 AsmWriteMm5 (
490 IN UINT64 Value
491 )
492 {
493 __asm__ __volatile__ (
494 "movq %0, %%mm5" // %0
495 :
496 : "m" (Value)
497 );
498 }
499
500 /**
501 Writes the current value of 64-bit MMX Register #6 (MM6).
502
503 Writes the current value of MM6. This function is only available on IA32 and
504 X64.
505
506 @param Value The 64-bit value to write to MM6.
507
508 **/
509 VOID
510 EFIAPI
511 AsmWriteMm6 (
512 IN UINT64 Value
513 )
514 {
515 __asm__ __volatile__ (
516 "movq %0, %%mm6" // %0
517 :
518 : "m" (Value)
519 );
520 }
521
522 /**
523 Writes the current value of 64-bit MMX Register #7 (MM7).
524
525 Writes the current value of MM7. This function is only available on IA32 and
526 X64.
527
528 @param Value The 64-bit value to write to MM7.
529
530 **/
531 VOID
532 EFIAPI
533 AsmWriteMm7 (
534 IN UINT64 Value
535 )
536 {
537 __asm__ __volatile__ (
538 "movq %0, %%mm7" // %0
539 :
540 : "m" (Value)
541 );
542 }
543
544 /**
545 Reads the current value of Time Stamp Counter (TSC).
546
547 Reads and returns the current value of TSC. This function is only available
548 on IA-32 and X64.
549
550 @return The current value of TSC
551
552 **/
553 UINT64
554 EFIAPI
555 AsmReadTsc (
556 VOID
557 )
558 {
559 UINT64 Data;
560
561 __asm__ __volatile__ (
562 "rdtsc"
563 : "=A" (Data)
564 );
565
566 return Data;
567 }