]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/x86LowLevel.c
1. Add Assert in SetJump.S
[mirror_edk2.git] / MdePkg / Library / BaseLib / x86LowLevel.c
CommitLineData
878ddf1f 1/** @file\r
2 IA-32/x64 specific functions.\r
3\r
4 Copyright (c) 2006, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13 Module Name: x86LowLevel.c\r
14\r
15**/\r
16\r
17#include "BaseLibInternals.h"\r
18\r
19//\r
20// Bit-wise MSR operations\r
21//\r
22\r
23/**\r
24 Reads a 64-bit MSR, performs a bitwise inclusive OR on the lower 32-bits, and\r
25 writes the result back to the 64-bit MSR.\r
26\r
27 Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR\r
28 between the lower 32-bits of the read result and the value specified by\r
29 OrData, and writes the result to the 64-bit MSR specified by Index. The lower\r
30 32-bits of the value written to the MSR is returned. No parameter checking is\r
31 performed on Index or OrData, and some of these may cause CPU exceptions. The\r
32 caller must either guarantee that Index and OrData are valid, or the caller\r
33 must establish proper exception handlers. This function is only available on\r
34 IA-32 and X64.\r
35\r
36 @param Index The 32-bit MSR index to write.\r
37 @param OrData The value to OR with the read value from the MSR.\r
38\r
39 @return The lower 32-bit value written to the MSR.\r
40\r
41**/\r
42UINT32\r
43EFIAPI\r
44AsmMsrOr32 (\r
45 IN UINT32 Index,\r
46 IN UINT32 OrData\r
47 )\r
48{\r
49 return (UINT32)AsmMsrOr64 (Index, OrData);\r
50}\r
51\r
52/**\r
53 Reads a 64-bit MSR, performs a bitwise AND on the lower 32-bits, and writes\r
54 the result back to the 64-bit MSR.\r
55\r
56 Reads the 64-bit MSR specified by Index, performs a bitwise AND between the\r
57 lower 32-bits of the read result and the value specified by AndData, and\r
58 writes the result to the 64-bit MSR specified by Index. The lower 32-bits of\r
59 the value written to the MSR is returned. No parameter checking is performed\r
60 on Index or AndData, and some of these may cause CPU exceptions. The caller\r
61 must either guarantee that Index and AndData are valid, or the caller must\r
62 establish proper exception handlers. This function is only available on IA-32\r
63 and X64.\r
64\r
65 @param Index The 32-bit MSR index to write.\r
66 @param AndData The value to AND with the read value from the MSR.\r
67\r
68 @return The lower 32-bit value written to the MSR.\r
69\r
70**/\r
71UINT32\r
72EFIAPI\r
73AsmMsrAnd32 (\r
74 IN UINT32 Index,\r
75 IN UINT32 AndData\r
76 )\r
77{\r
78 return (UINT32)AsmMsrAnd64 (Index, AndData);\r
79}\r
80\r
81/**\r
82 Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise inclusive OR\r
83 on the lower 32-bits, and writes the result back to the 64-bit MSR.\r
84\r
85 Reads the 64-bit MSR specified by Index, performs a bitwise AND between the\r
86 lower 32-bits of the read result and the value specified by AndData\r
87 preserving the upper 32-bits, performs a bitwise inclusive OR between the\r
88 result of the AND operation and the value specified by OrData, and writes the\r
89 result to the 64-bit MSR specified by Address. The lower 32-bits of the value\r
90 written to the MSR is returned. No parameter checking is performed on Index,\r
91 AndData, or OrData, and some of these may cause CPU exceptions. The caller\r
92 must either guarantee that Index, AndData, and OrData are valid, or the\r
93 caller must establish proper exception handlers. This function is only\r
94 available on IA-32 and X64.\r
95\r
96 @param Index The 32-bit MSR index to write.\r
97 @param AndData The value to AND with the read value from the MSR.\r
98 @param OrData The value to OR with the result of the AND operation.\r
99\r
100 @return The lower 32-bit value written to the MSR.\r
101\r
102**/\r
103UINT32\r
104EFIAPI\r
105AsmMsrAndThenOr32 (\r
106 IN UINT32 Index,\r
107 IN UINT32 AndData,\r
108 IN UINT32 OrData\r
109 )\r
110{\r
111 return (UINT32)AsmMsrAndThenOr64 (Index, AndData, OrData);\r
112}\r
113\r
114/**\r
115 Reads a bit field of an MSR.\r
116\r
117 Reads the bit field in the lower 32-bits of a 64-bit MSR. The bit field is\r
118 specified by the StartBit and the EndBit. The value of the bit field is\r
119 returned. The caller must either guarantee that Index is valid, or the caller\r
120 must set up exception handlers to catch the exceptions. This function is only\r
121 available on IA-32 and X64.\r
122\r
123 If StartBit is greater than 31, then ASSERT().\r
124 If EndBit is greater than 31, then ASSERT().\r
0ffa1286 125 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 126\r
127 @param Index The 32-bit MSR index to read.\r
128 @param StartBit The ordinal of the least significant bit in the bit field.\r
129 Range 0..31.\r
130 @param EndBit The ordinal of the most significant bit in the bit field.\r
131 Range 0..31.\r
132\r
133 @return The bit field read from the MSR.\r
134\r
135**/\r
136UINT32\r
137EFIAPI\r
138AsmMsrBitFieldRead32 (\r
139 IN UINT32 Index,\r
140 IN UINTN StartBit,\r
141 IN UINTN EndBit\r
142 )\r
143{\r
144 return BitFieldRead32 (AsmReadMsr32 (Index), StartBit, EndBit);\r
145}\r
146\r
147/**\r
148 Writes a bit field to an MSR.\r
149\r
150 Writes Value to a bit field in the lower 32-bits of a 64-bit MSR. The bit\r
151 field is specified by the StartBit and the EndBit. All other bits in the\r
152 destination MSR are preserved. The lower 32-bits of the MSR written is\r
153 returned. Extra left bits in Value are stripped. The caller must either\r
154 guarantee that Index and the data written is valid, or the caller must set up\r
155 exception handlers to catch the exceptions. This function is only available\r
156 on IA-32 and X64.\r
157\r
158 If StartBit is greater than 31, then ASSERT().\r
159 If EndBit is greater than 31, then ASSERT().\r
0ffa1286 160 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 161\r
162 @param Index The 32-bit MSR index to write.\r
163 @param StartBit The ordinal of the least significant bit in the bit field.\r
164 Range 0..31.\r
165 @param EndBit The ordinal of the most significant bit in the bit field.\r
166 Range 0..31.\r
167 @param Value New value of the bit field.\r
168\r
169 @return The lower 32-bit of the value written to the MSR.\r
170\r
171**/\r
172UINT32\r
173EFIAPI\r
174AsmMsrBitFieldWrite32 (\r
175 IN UINT32 Index,\r
176 IN UINTN StartBit,\r
177 IN UINTN EndBit,\r
178 IN UINT32 Value\r
179 )\r
180{\r
181 ASSERT (EndBit < sizeof (Value) * 8);\r
182 ASSERT (StartBit <= EndBit);\r
183 return (UINT32)AsmMsrBitFieldWrite64 (Index, StartBit, EndBit, Value);\r
184}\r
185\r
186/**\r
187 Reads a bit field in a 64-bit MSR, performs a bitwise OR, and writes the\r
188 result back to the bit field in the 64-bit MSR.\r
189\r
190 Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR\r
191 between the read result and the value specified by OrData, and writes the\r
192 result to the 64-bit MSR specified by Index. The lower 32-bits of the value\r
193 written to the MSR are returned. Extra left bits in OrData are stripped. The\r
194 caller must either guarantee that Index and the data written is valid, or\r
195 the caller must set up exception handlers to catch the exceptions. This\r
196 function is only available on IA-32 and X64.\r
197\r
198 If StartBit is greater than 31, then ASSERT().\r
199 If EndBit is greater than 31, then ASSERT().\r
0ffa1286 200 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 201\r
202 @param Index The 32-bit MSR index to write.\r
203 @param StartBit The ordinal of the least significant bit in the bit field.\r
204 Range 0..31.\r
205 @param EndBit The ordinal of the most significant bit in the bit field.\r
206 Range 0..31.\r
207 @param OrData The value to OR with the read value from the MSR.\r
208\r
209 @return The lower 32-bit of the value written to the MSR.\r
210\r
211**/\r
212UINT32\r
213EFIAPI\r
214AsmMsrBitFieldOr32 (\r
215 IN UINT32 Index,\r
216 IN UINTN StartBit,\r
217 IN UINTN EndBit,\r
218 IN UINT32 OrData\r
219 )\r
220{\r
221 ASSERT (EndBit < sizeof (OrData) * 8);\r
222 ASSERT (StartBit <= EndBit);\r
223 return (UINT32)AsmMsrBitFieldOr64 (Index, StartBit, EndBit, OrData);\r
224}\r
225\r
226/**\r
227 Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the\r
228 result back to the bit field in the 64-bit MSR.\r
229\r
230 Reads the 64-bit MSR specified by Index, performs a bitwise AND between the\r
231 read result and the value specified by AndData, and writes the result to the\r
232 64-bit MSR specified by Index. The lower 32-bits of the value written to the\r
233 MSR are returned. Extra left bits in AndData are stripped. The caller must\r
234 either guarantee that Index and the data written is valid, or the caller must\r
235 set up exception handlers to catch the exceptions. This function is only\r
236 available on IA-32 and X64.\r
237\r
238 If StartBit is greater than 31, then ASSERT().\r
239 If EndBit is greater than 31, then ASSERT().\r
0ffa1286 240 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 241\r
242 @param Index The 32-bit MSR index to write.\r
243 @param StartBit The ordinal of the least significant bit in the bit field.\r
244 Range 0..31.\r
245 @param EndBit The ordinal of the most significant bit in the bit field.\r
246 Range 0..31.\r
247 @param AndData The value to AND with the read value from the MSR.\r
248\r
249 @return The lower 32-bit of the value written to the MSR.\r
250\r
251**/\r
252UINT32\r
253EFIAPI\r
254AsmMsrBitFieldAnd32 (\r
255 IN UINT32 Index,\r
256 IN UINTN StartBit,\r
257 IN UINTN EndBit,\r
258 IN UINT32 AndData\r
259 )\r
260{\r
261 ASSERT (EndBit < sizeof (AndData) * 8);\r
262 ASSERT (StartBit <= EndBit);\r
263 return (UINT32)AsmMsrBitFieldAnd64 (Index, StartBit, EndBit, AndData);\r
264}\r
265\r
266/**\r
267 Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a\r
268 bitwise inclusive OR, and writes the result back to the bit field in the\r
269 64-bit MSR.\r
270\r
271 Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by a\r
272 bitwise inclusive OR between the read result and the value specified by\r
273 AndData, and writes the result to the 64-bit MSR specified by Index. The\r
274 lower 32-bits of the value written to the MSR are returned. Extra left bits\r
275 in both AndData and OrData are stripped. The caller must either guarantee\r
276 that Index and the data written is valid, or the caller must set up exception\r
277 handlers to catch the exceptions. This function is only available on IA-32\r
278 and X64.\r
279\r
280 If StartBit is greater than 31, then ASSERT().\r
281 If EndBit is greater than 31, then ASSERT().\r
0ffa1286 282 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 283\r
284 @param Index The 32-bit MSR index to write.\r
285 @param StartBit The ordinal of the least significant bit in the bit field.\r
286 Range 0..31.\r
287 @param EndBit The ordinal of the most significant bit in the bit field.\r
288 Range 0..31.\r
289 @param AndData The value to AND with the read value from the MSR.\r
290 @param OrData The value to OR with the result of the AND operation.\r
291\r
292 @return The lower 32-bit of the value written to the MSR.\r
293\r
294**/\r
295UINT32\r
296EFIAPI\r
297AsmMsrBitFieldAndThenOr32 (\r
298 IN UINT32 Index,\r
299 IN UINTN StartBit,\r
300 IN UINTN EndBit,\r
301 IN UINT32 AndData,\r
302 IN UINT32 OrData\r
303 )\r
304{\r
305 ASSERT (EndBit < sizeof (AndData) * 8);\r
306 ASSERT (StartBit <= EndBit);\r
307 return (UINT32)AsmMsrBitFieldAndThenOr64 (\r
308 Index,\r
309 StartBit,\r
310 EndBit,\r
311 AndData,\r
312 OrData\r
313 );\r
314}\r
315\r
316/**\r
317 Reads a 64-bit MSR, performs a bitwise inclusive OR, and writes the result\r
318 back to the 64-bit MSR.\r
319\r
320 Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR\r
321 between the read result and the value specified by OrData, and writes the\r
322 result to the 64-bit MSR specified by Index. The value written to the MSR is\r
323 returned. No parameter checking is performed on Index or OrData, and some of\r
324 these may cause CPU exceptions. The caller must either guarantee that Index\r
325 and OrData are valid, or the caller must establish proper exception handlers.\r
326 This function is only available on IA-32 and X64.\r
327\r
328 @param Index The 32-bit MSR index to write.\r
329 @param OrData The value to OR with the read value from the MSR.\r
330\r
331 @return The value written back to the MSR.\r
332\r
333**/\r
334UINT64\r
335EFIAPI\r
336AsmMsrOr64 (\r
337 IN UINT32 Index,\r
338 IN UINT64 OrData\r
339 )\r
340{\r
341 return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) | OrData);\r
342}\r
343\r
344/**\r
345 Reads a 64-bit MSR, performs a bitwise AND, and writes the result back to the\r
346 64-bit MSR.\r
347\r
348 Reads the 64-bit MSR specified by Index, performs a bitwise AND between the\r
349 read result and the value specified by OrData, and writes the result to the\r
350 64-bit MSR specified by Index. The value written to the MSR is returned. No\r
351 parameter checking is performed on Index or OrData, and some of these may\r
352 cause CPU exceptions. The caller must either guarantee that Index and OrData\r
353 are valid, or the caller must establish proper exception handlers. This\r
354 function is only available on IA-32 and X64.\r
355\r
356 @param Index The 32-bit MSR index to write.\r
357 @param AndData The value to AND with the read value from the MSR.\r
358\r
359 @return The value written back to the MSR.\r
360\r
361**/\r
362UINT64\r
363EFIAPI\r
364AsmMsrAnd64 (\r
365 IN UINT32 Index,\r
366 IN UINT64 AndData\r
367 )\r
368{\r
369 return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) & AndData);\r
370}\r
371\r
372/**\r
373 Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise inclusive\r
374 OR, and writes the result back to the 64-bit MSR.\r
375\r
376 Reads the 64-bit MSR specified by Index, performs a bitwise AND between read\r
377 result and the value specified by AndData, performs a bitwise inclusive OR\r
378 between the result of the AND operation and the value specified by OrData,\r
379 and writes the result to the 64-bit MSR specified by Index. The value written\r
380 to the MSR is returned. No parameter checking is performed on Index, AndData,\r
381 or OrData, and some of these may cause CPU exceptions. The caller must either\r
382 guarantee that Index, AndData, and OrData are valid, or the caller must\r
383 establish proper exception handlers. This function is only available on IA-32\r
384 and X64.\r
385\r
386 @param Index The 32-bit MSR index to write.\r
387 @param AndData The value to AND with the read value from the MSR.\r
388 @param OrData The value to OR with the result of the AND operation.\r
389\r
390 @return The value written back to the MSR.\r
391\r
392**/\r
393UINT64\r
394EFIAPI\r
395AsmMsrAndThenOr64 (\r
396 IN UINT32 Index,\r
397 IN UINT64 AndData,\r
398 IN UINT64 OrData\r
399 )\r
400{\r
401 return AsmWriteMsr64 (Index, (AsmReadMsr64 (Index) & AndData) | OrData);\r
402}\r
403\r
404/**\r
405 Reads a bit field of an MSR.\r
406\r
407 Reads the bit field in the 64-bit MSR. The bit field is specified by the\r
408 StartBit and the EndBit. The value of the bit field is returned. The caller\r
409 must either guarantee that Index is valid, or the caller must set up\r
410 exception handlers to catch the exceptions. This function is only available\r
411 on IA-32 and X64.\r
412\r
413 If StartBit is greater than 63, then ASSERT().\r
414 If EndBit is greater than 63, then ASSERT().\r
0ffa1286 415 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 416\r
417 @param Index The 32-bit MSR index to read.\r
418 @param StartBit The ordinal of the least significant bit in the bit field.\r
419 Range 0..63.\r
420 @param EndBit The ordinal of the most significant bit in the bit field.\r
421 Range 0..63.\r
422\r
423 @return The value written back to the MSR.\r
424\r
425**/\r
426UINT64\r
427EFIAPI\r
428AsmMsrBitFieldRead64 (\r
429 IN UINT32 Index,\r
430 IN UINTN StartBit,\r
431 IN UINTN EndBit\r
432 )\r
433{\r
434 return BitFieldRead64 (AsmReadMsr64 (Index), StartBit, EndBit);\r
435}\r
436\r
437/**\r
438 Writes a bit field to an MSR.\r
439\r
440 Writes Value to a bit field in a 64-bit MSR. The bit field is specified by\r
441 the StartBit and the EndBit. All other bits in the destination MSR are\r
442 preserved. The MSR written is returned. Extra left bits in Value are\r
443 stripped. The caller must either guarantee that Index and the data written is\r
444 valid, or the caller must set up exception handlers to catch the exceptions.\r
445 This function is only available on IA-32 and X64.\r
446\r
447 If StartBit is greater than 63, then ASSERT().\r
448 If EndBit is greater than 63, then ASSERT().\r
0ffa1286 449 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 450\r
451 @param Index The 32-bit MSR index to write.\r
452 @param StartBit The ordinal of the least significant bit in the bit field.\r
453 Range 0..63.\r
454 @param EndBit The ordinal of the most significant bit in the bit field.\r
455 Range 0..63.\r
456 @param Value New value of the bit field.\r
457\r
458 @return The value written back to the MSR.\r
459\r
460**/\r
461UINT64\r
462EFIAPI\r
463AsmMsrBitFieldWrite64 (\r
464 IN UINT32 Index,\r
465 IN UINTN StartBit,\r
466 IN UINTN EndBit,\r
467 IN UINT64 Value\r
468 )\r
469{\r
470 return AsmWriteMsr64 (\r
471 Index,\r
472 BitFieldWrite64 (AsmReadMsr64 (Index), StartBit, EndBit, Value)\r
473 );\r
474}\r
475\r
476/**\r
477 Reads a bit field in a 64-bit MSR, performs a bitwise inclusive OR, and\r
478 writes the result back to the bit field in the 64-bit MSR.\r
479\r
480 Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR\r
481 between the read result and the value specified by OrData, and writes the\r
482 result to the 64-bit MSR specified by Index. The value written to the MSR is\r
483 returned. Extra left bits in OrData are stripped. The caller must either\r
484 guarantee that Index and the data written is valid, or the caller must set up\r
485 exception handlers to catch the exceptions. This function is only available\r
486 on IA-32 and X64.\r
487\r
488 If StartBit is greater than 63, then ASSERT().\r
489 If EndBit is greater than 63, then ASSERT().\r
0ffa1286 490 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 491\r
492 @param Index The 32-bit MSR index to write.\r
493 @param StartBit The ordinal of the least significant bit in the bit field.\r
494 Range 0..63.\r
495 @param EndBit The ordinal of the most significant bit in the bit field.\r
496 Range 0..63.\r
497 @param OrData The value to OR with the read value from the bit field.\r
498\r
499 @return The value written back to the MSR.\r
500\r
501**/\r
502UINT64\r
503EFIAPI\r
504AsmMsrBitFieldOr64 (\r
505 IN UINT32 Index,\r
506 IN UINTN StartBit,\r
507 IN UINTN EndBit,\r
508 IN UINT64 OrData\r
509 )\r
510{\r
511 return AsmWriteMsr64 (\r
512 Index,\r
513 BitFieldOr64 (AsmReadMsr64 (Index), StartBit, EndBit, OrData)\r
514 );\r
515}\r
516\r
517/**\r
518 Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the\r
519 result back to the bit field in the 64-bit MSR.\r
520\r
521 Reads the 64-bit MSR specified by Index, performs a bitwise AND between the\r
522 read result and the value specified by AndData, and writes the result to the\r
523 64-bit MSR specified by Index. The value written to the MSR is returned.\r
524 Extra left bits in AndData are stripped. The caller must either guarantee\r
525 that Index and the data written is valid, or the caller must set up exception\r
526 handlers to catch the exceptions. This function is only available on IA-32\r
527 and X64.\r
528\r
529 If StartBit is greater than 63, then ASSERT().\r
530 If EndBit is greater than 63, then ASSERT().\r
0ffa1286 531 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 532\r
533 @param Index The 32-bit MSR index to write.\r
534 @param StartBit The ordinal of the least significant bit in the bit field.\r
535 Range 0..63.\r
536 @param EndBit The ordinal of the most significant bit in the bit field.\r
537 Range 0..63.\r
538 @param AndData The value to AND with the read value from the bit field.\r
539\r
540 @return The value written back to the MSR.\r
541\r
542**/\r
543UINT64\r
544EFIAPI\r
545AsmMsrBitFieldAnd64 (\r
546 IN UINT32 Index,\r
547 IN UINTN StartBit,\r
548 IN UINTN EndBit,\r
549 IN UINT64 AndData\r
550 )\r
551{\r
552 return AsmWriteMsr64 (\r
553 Index,\r
554 BitFieldAnd64 (AsmReadMsr64 (Index), StartBit, EndBit, AndData)\r
555 );\r
556}\r
557\r
558/**\r
559 Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a\r
560 bitwise inclusive OR, and writes the result back to the bit field in the\r
561 64-bit MSR.\r
562\r
563 Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by\r
564 a bitwise inclusive OR between the read result and the value specified by\r
565 AndData, and writes the result to the 64-bit MSR specified by Index. The\r
566 value written to the MSR is returned. Extra left bits in both AndData and\r
567 OrData are stripped. The caller must either guarantee that Index and the data\r
568 written is valid, or the caller must set up exception handlers to catch the\r
569 exceptions. This function is only available on IA-32 and X64.\r
570\r
571 If StartBit is greater than 63, then ASSERT().\r
572 If EndBit is greater than 63, then ASSERT().\r
0ffa1286 573 If EndBit is less than StartBit, then ASSERT().\r
878ddf1f 574\r
575 @param Index The 32-bit MSR index to write.\r
576 @param StartBit The ordinal of the least significant bit in the bit field.\r
577 Range 0..63.\r
578 @param EndBit The ordinal of the most significant bit in the bit field.\r
579 Range 0..63.\r
580 @param AndData The value to AND with the read value from the bit field.\r
581 @param OrData The value to OR with the result of the AND operation.\r
582\r
583 @return The value written back to the MSR.\r
584\r
585**/\r
586UINT64\r
587EFIAPI\r
588AsmMsrBitFieldAndThenOr64 (\r
589 IN UINT32 Index,\r
590 IN UINTN StartBit,\r
591 IN UINTN EndBit,\r
592 IN UINT64 AndData,\r
593 IN UINT64 OrData\r
594 )\r
595{\r
596 return AsmWriteMsr64 (\r
597 Index,\r
598 BitFieldAndThenOr64 (\r
599 AsmReadMsr64 (Index),\r
600 StartBit,\r
601 EndBit,\r
602 AndData,\r
603 OrData\r
604 )\r
605 );\r
606}\r
607\r
608//\r
609// Base Library CPU Functions\r
610//\r
611\r
612/**\r
613 Retrieves the current CPU interrupt state.\r
614\r
615 Retrieves the current CPU interrupt state. Returns TRUE is interrupts are\r
616 currently enabled. Otherwise returns FALSE.\r
617\r
618 @retval TRUE CPU interrupts are enabled.\r
619 @retval FALSE CPU interrupts are disabled.\r
620\r
621**/\r
622BOOLEAN\r
623EFIAPI\r
624GetInterruptState (\r
625 VOID\r
626 )\r
627{\r
628 IA32_EFLAGS32 EFlags;\r
629\r
630 EFlags.UintN = AsmReadEflags ();\r
631 return (BOOLEAN)(EFlags.Bits.IF == 1);\r
632}\r
633\r
634//\r
635// Ia32 and x64 specific functions\r
636//\r
637\r
638/**\r
639 Reads the current Global Descriptor Table Register(GDTR) descriptor.\r
640\r
641 Reads and returns the current GDTR descriptor and returns it in Gdtr. This\r
642 function is only available on IA-32 and X64.\r
643\r
644 If Gdtr is NULL, then ASSERT().\r
645\r
646 @param Gdtr Pointer to a GDTR descriptor.\r
647\r
648**/\r
649VOID\r
650EFIAPI\r
651AsmReadGdtr (\r
652 OUT IA32_DESCRIPTOR *Gdtr\r
653 )\r
654{\r
655 ASSERT (Gdtr != NULL);\r
656 InternalX86ReadGdtr (Gdtr);\r
657}\r
658\r
659/**\r
660 Writes the current Global Descriptor Table Register (GDTR) descriptor.\r
661\r
662 Writes and the current GDTR descriptor specified by Gdtr. This function is\r
663 only available on IA-32 and X64.\r
664\r
665 If Gdtr is NULL, then ASSERT().\r
666\r
667 @param Gdtr Pointer to a GDTR descriptor.\r
668\r
669**/\r
670VOID\r
671EFIAPI\r
672AsmWriteGdtr (\r
673 IN CONST IA32_DESCRIPTOR *Gdtr\r
674 )\r
675{\r
676 ASSERT (Gdtr != NULL);\r
677 InternalX86WriteGdtr (Gdtr);\r
678}\r
679\r
680/**\r
681 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.\r
682\r
683 Reads and returns the current IDTR descriptor and returns it in Idtr. This\r
684 function is only available on IA-32 and X64.\r
685\r
686 If Idtr is NULL, then ASSERT().\r
687\r
688 @param Idtr Pointer to a IDTR descriptor.\r
689\r
690**/\r
691VOID\r
692EFIAPI\r
693AsmReadIdtr (\r
694 OUT IA32_DESCRIPTOR *Idtr\r
695 )\r
696{\r
697 ASSERT (Idtr != NULL);\r
698 InternalX86ReadIdtr (Idtr);\r
699}\r
700\r
701/**\r
702 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.\r
703\r
704 Writes the current IDTR descriptor and returns it in Idtr. This function is\r
705 only available on IA-32 and X64.\r
706\r
707 If Idtr is NULL, then ASSERT().\r
708\r
709 @param Idtr Pointer to a IDTR descriptor.\r
710\r
711**/\r
712VOID\r
713EFIAPI\r
714AsmWriteIdtr (\r
715 IN CONST IA32_DESCRIPTOR *Idtr\r
716 )\r
717{\r
718 ASSERT (Idtr != NULL);\r
719 InternalX86WriteIdtr (Idtr);\r
720}\r
721\r
722/**\r
723 Save the current floating point/SSE/SSE2 context to a buffer.\r
724\r
725 Saves the current floating point/SSE/SSE2 state to the buffer specified by\r
726 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only\r
727 available on IA-32 and X64.\r
728\r
729 If Buffer is NULL, then ASSERT().\r
730 If Buffer is not aligned on a 16-byte boundary, then ASSERT().\r
731\r
732 @param Buffer Pointer to a buffer to save the floating point/SSE/SSE2 context.\r
733\r
734**/\r
735VOID\r
736EFIAPI\r
737AsmFxSave (\r
738 OUT IA32_FX_BUFFER *Buffer\r
739 )\r
740{\r
741 ASSERT (Buffer != NULL);\r
742 ASSERT (((UINTN)Buffer & 0xf) == 0);\r
0ffa1286 743\r
878ddf1f 744 InternalX86FxSave (Buffer);\r
0ffa1286 745 \r
746 //\r
747 // Mark one flag at end of Buffer, it will be check by AsmFxRestor()\r
748 //\r
749 *(UINT32 *) (&Buffer[sizeof (IA32_FX_BUFFER) - 4]) = 0xAA5555AA; \r
878ddf1f 750}\r
751\r
752/**\r
753 Restores the current floating point/SSE/SSE2 context from a buffer.\r
754\r
755 Restores the current floating point/SSE/SSE2 state from the buffer specified\r
756 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is\r
757 only available on IA-32 and X64.\r
758\r
759 If Buffer is NULL, then ASSERT().\r
760 If Buffer is not aligned on a 16-byte boundary, then ASSERT().\r
761 If Buffer was not saved with AsmFxSave(), then ASSERT().\r
762\r
763 @param Buffer Pointer to a buffer to save the floating point/SSE/SSE2 context.\r
764\r
765**/\r
766VOID\r
767EFIAPI\r
768AsmFxRestore (\r
769 IN CONST IA32_FX_BUFFER *Buffer\r
770 )\r
771{\r
772 ASSERT (Buffer != NULL);\r
773 ASSERT (((UINTN)Buffer & 0xf) == 0);\r
0ffa1286 774\r
775 //\r
776 // Check the flag recorded by AsmFxSave()\r
777 //\r
778 ASSERT (*(UINT32 *) (&Buffer[sizeof (IA32_FX_BUFFER) - 4]) == 0xAA5555AA);\r
779\r
878ddf1f 780 InternalX86FxRestore (Buffer);\r
781}\r
782\r
783/**\r
784 Enables the 32-bit paging mode on the CPU.\r
785\r
786 Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables\r
787 must be properly initialized prior to calling this service. This function\r
788 assumes the current execution mode is 32-bit protected mode. This function is\r
789 only available on IA-32. After the 32-bit paging mode is enabled, control is\r
790 transferred to the function specified by EntryPoint using the new stack\r
791 specified by NewStack and passing in the parameters specified by Context1 and\r
792 Context2. Context1 and Context2 are optional and may be NULL. The function\r
793 EntryPoint must never return.\r
794\r
795 If the current execution mode is not 32-bit protected mode, then ASSERT().\r
796 If EntryPoint is NULL, then ASSERT().\r
797 If NewStack is NULL, then ASSERT().\r
798\r
799 There are a number of constraints that must be followed before calling this\r
800 function:\r
801 1) Interrupts must be disabled.\r
802 2) The caller must be in 32-bit protected mode with flat descriptors. This\r
803 means all descriptors must have a base of 0 and a limit of 4GB.\r
804 3) CR0 and CR4 must be compatible with 32-bit protected mode with flat\r
805 descriptors.\r
806 4) CR3 must point to valid page tables that will be used once the transition\r
807 is complete, and those page tables must guarantee that the pages for this\r
808 function and the stack are identity mapped.\r
809\r
810 @param EntryPoint A pointer to function to call with the new stack after\r
811 paging is enabled.\r
812 @param Context1 A pointer to the context to pass into the EntryPoint\r
813 function as the first parameter after paging is enabled.\r
814 @param Context2 A pointer to the context to pass into the EntryPoint\r
815 function as the second parameter after paging is enabled.\r
816 @param NewStack A pointer to the new stack to use for the EntryPoint\r
817 function after paging is enabled.\r
818\r
819**/\r
820VOID\r
821EFIAPI\r
822AsmEnablePaging32 (\r
823 IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
824 IN VOID *Context1, OPTIONAL\r
825 IN VOID *Context2, OPTIONAL\r
826 IN VOID *NewStack\r
827 )\r
828{\r
829 ASSERT (EntryPoint != NULL);\r
830 ASSERT (NewStack != NULL);\r
831 InternalX86EnablePaging32 (EntryPoint, Context1, Context2, NewStack);\r
832}\r
833\r
834/**\r
835 Disables the 32-bit paging mode on the CPU.\r
836\r
837 Disables the 32-bit paging mode on the CPU and returns to 32-bit protected\r
838 mode. This function assumes the current execution mode is 32-paged protected\r
839 mode. This function is only available on IA-32. After the 32-bit paging mode\r
840 is disabled, control is transferred to the function specified by EntryPoint\r
841 using the new stack specified by NewStack and passing in the parameters\r
842 specified by Context1 and Context2. Context1 and Context2 are optional and\r
843 may be NULL. The function EntryPoint must never return.\r
844\r
845 If the current execution mode is not 32-bit paged mode, then ASSERT().\r
846 If EntryPoint is NULL, then ASSERT().\r
847 If NewStack is NULL, then ASSERT().\r
848\r
849 There are a number of constraints that must be followed before calling this\r
850 function:\r
851 1) Interrupts must be disabled.\r
852 2) The caller must be in 32-bit paged mode.\r
853 3) CR0, CR3, and CR4 must be compatible with 32-bit paged mode.\r
854 4) CR3 must point to valid page tables that guarantee that the pages for\r
855 this function and the stack are identity mapped.\r
856\r
857 @param EntryPoint A pointer to function to call with the new stack after\r
858 paging is disabled.\r
859 @param Context1 A pointer to the context to pass into the EntryPoint\r
860 function as the first parameter after paging is disabled.\r
861 @param Context2 A pointer to the context to pass into the EntryPoint\r
862 function as the second parameter after paging is\r
863 disabled.\r
864 @param NewStack A pointer to the new stack to use for the EntryPoint\r
865 function after paging is disabled.\r
866\r
867**/\r
868VOID\r
869EFIAPI\r
870AsmDisablePaging32 (\r
871 IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
872 IN VOID *Context1, OPTIONAL\r
873 IN VOID *Context2, OPTIONAL\r
874 IN VOID *NewStack\r
875 )\r
876{\r
877 ASSERT (EntryPoint != NULL);\r
878 ASSERT (NewStack != NULL);\r
879 InternalX86DisablePaging32 (EntryPoint, Context1, Context2, NewStack);\r
880}\r
881\r
882/**\r
883 Enables the 64-bit paging mode on the CPU.\r
884\r
885 Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables\r
886 must be properly initialized prior to calling this service. This function\r
887 assumes the current execution mode is 32-bit protected mode with flat\r
888 descriptors. This function is only available on IA-32. After the 64-bit\r
889 paging mode is enabled, control is transferred to the function specified by\r
890 EntryPoint using the new stack specified by NewStack and passing in the\r
891 parameters specified by Context1 and Context2. Context1 and Context2 are\r
892 optional and may be 0. The function EntryPoint must never return.\r
893\r
894 If the current execution mode is not 32-bit protected mode with flat\r
895 descriptors, then ASSERT().\r
896 If EntryPoint is 0, then ASSERT().\r
897 If NewStack is 0, then ASSERT().\r
898\r
899 @param Cs The 16-bit selector to load in the CS before EntryPoint\r
900 is called. The descriptor in the GDT that this selector\r
901 references must be setup for long mode.\r
902 @param EntryPoint The 64-bit virtual address of the function to call with\r
903 the new stack after paging is enabled.\r
904 @param Context1 The 64-bit virtual address of the context to pass into\r
905 the EntryPoint function as the first parameter after\r
906 paging is enabled.\r
907 @param Context2 The 64-bit virtual address of the context to pass into\r
908 the EntryPoint function as the second parameter after\r
909 paging is enabled.\r
910 @param NewStack The 64-bit virtual address of the new stack to use for\r
911 the EntryPoint function after paging is enabled.\r
912\r
913**/\r
914VOID\r
915EFIAPI\r
916AsmEnablePaging64 (\r
917 IN UINT16 Cs,\r
918 IN UINT64 EntryPoint,\r
919 IN UINT64 Context1, OPTIONAL\r
920 IN UINT64 Context2, OPTIONAL\r
921 IN UINT64 NewStack\r
922 )\r
923{\r
924 ASSERT (EntryPoint != 0);\r
925 ASSERT (NewStack != 0);\r
926 InternalX86EnablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);\r
927}\r
928\r
929/**\r
930 Disables the 64-bit paging mode on the CPU.\r
931\r
932 Disables the 64-bit paging mode on the CPU and returns to 32-bit protected\r
933 mode. This function assumes the current execution mode is 64-paging mode.\r
934 This function is only available on X64. After the 64-bit paging mode is\r
935 disabled, control is transferred to the function specified by EntryPoint\r
936 using the new stack specified by NewStack and passing in the parameters\r
937 specified by Context1 and Context2. Context1 and Context2 are optional and\r
938 may be 0. The function EntryPoint must never return.\r
939\r
940 If the current execution mode is not 64-bit paged mode, then ASSERT().\r
941 If EntryPoint is 0, then ASSERT().\r
942 If NewStack is 0, then ASSERT().\r
943\r
944 @param Cs The 16-bit selector to load in the CS before EntryPoint\r
945 is called. The descriptor in the GDT that this selector\r
946 references must be setup for 32-bit protected mode.\r
947 @param EntryPoint The 64-bit virtual address of the function to call with\r
948 the new stack after paging is disabled.\r
949 @param Context1 The 64-bit virtual address of the context to pass into\r
950 the EntryPoint function as the first parameter after\r
951 paging is disabled.\r
952 @param Context2 The 64-bit virtual address of the context to pass into\r
953 the EntryPoint function as the second parameter after\r
954 paging is disabled.\r
955 @param NewStack The 64-bit virtual address of the new stack to use for\r
956 the EntryPoint function after paging is disabled.\r
957\r
958**/\r
959VOID\r
960EFIAPI\r
961AsmDisablePaging64 (\r
962 IN UINT16 Cs,\r
963 IN UINT32 EntryPoint,\r
964 IN UINT32 Context1, OPTIONAL\r
965 IN UINT32 Context2, OPTIONAL\r
966 IN UINT32 NewStack\r
967 )\r
968{\r
969 ASSERT (EntryPoint != 0);\r
970 ASSERT (NewStack != 0);\r
971 InternalX86DisablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);\r
972}\r
973\r
974//\r
975// x86 version of MemoryFence()\r
976//\r
977\r
978/**\r
979 Used to serialize load and store operations.\r
980\r
981 All loads and stores that proceed calls to this function are guaranteed to be\r
982 globally visible when this function returns.\r
983\r
984**/\r
985VOID\r
986EFIAPI\r
987MemoryFence (\r
988 VOID\r
989 )\r
990{\r
991}\r