1 /*++
2 
3 Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 
13 Module Name:
14 
15   BaseLibInternals.h
16 
17 Abstract:
18 
19   Declaration of internal functions in BaseLib.
20 
21 --*/
22 
23 #ifndef __BASE_LIB_INTERNALS_H__
24 #define __BASE_LIB_INTERNALS_H__
25 
26 #include "EdkIIGlueBase.h"
27 
28 #define QUIENT_MAX_UINTN_DIVIDED_BY_10      ((UINTN) -1 / 10)
29 #define REMINDER_MAX_UINTN_DIVIDED_BY_10    ((UINTN) -1 % 10)
30 
31 #define QUIENT_MAX_UINTN_DIVIDED_BY_16      ((UINTN) -1 / 16)
32 #define REMINDER_MAX_UINTN_DIVIDED_BY_16    ((UINTN) -1 % 16)
33 
34 #define QUIENT_MAX_UINT64_DIVIDED_BY_10      ((UINT64) -1 / 10)
35 #define REMINDER_MAX_UINT64_DIVIDED_BY_10    ((UINT64) -1 % 10)
36 
37 #define QUIENT_MAX_UINT64_DIVIDED_BY_16      ((UINT64) -1 / 16)
38 #define REMINDER_MAX_UINT64_DIVIDED_BY_16    ((UINT64) -1 % 16)
39 
40 //
41 // Math functions
42 //
43 
44 /**
45   Shifts a 64-bit integer left between 0 and 63 bits. The low bits
46   are filled with zeros. The shifted value is returned.
47 
48   This function shifts the 64-bit value Operand to the left by Count bits. The
49   low Count bits are set to zero. The shifted value is returned.
50 
51   @param  Operand The 64-bit operand to shift left.
52   @param  Count   The number of bits to shift left.
53 
54   @return Operand << Count
55 
56 **/
57 UINT64
58 EFIAPI
59 InternalMathLShiftU64 (
60   IN      UINT64                    Operand,
61   IN      UINTN                     Count
62   );
63 
64 /**
65   Shifts a 64-bit integer right between 0 and 63 bits. This high bits
66   are filled with zeros. The shifted value is returned.
67 
68   This function shifts the 64-bit value Operand to the right by Count bits. The
69   high Count bits are set to zero. The shifted value is returned.
70 
71   @param  Operand The 64-bit operand to shift right.
72   @param  Count   The number of bits to shift right.
73 
74   @return Operand >> Count
75 
76 **/
77 UINT64
78 EFIAPI
79 InternalMathRShiftU64 (
80   IN      UINT64                    Operand,
81   IN      UINTN                     Count
82   );
83 
84 /**
85   Shifts a 64-bit integer right between 0 and 63 bits. The high bits
86   are filled with original integer's bit 63. The shifted value is returned.
87 
88   This function shifts the 64-bit value Operand to the right by Count bits. The
89   high Count bits are set to bit 63 of Operand.  The shifted value is returned.
90 
91   @param  Operand The 64-bit operand to shift right.
92   @param  Count   The number of bits to shift right.
93 
94   @return Operand arithmetically shifted right by Count
95 
96 **/
97 UINT64
98 EFIAPI
99 InternalMathARShiftU64 (
100   IN      UINT64                    Operand,
101   IN      UINTN                     Count
102   );
103 
104 /**
105   Rotates a 64-bit integer left between 0 and 63 bits, filling
106   the low bits with the high bits that were rotated.
107 
108   This function rotates the 64-bit value Operand to the left by Count bits. The
109   low Count bits are fill with the high Count bits of Operand. The rotated
110   value is returned.
111 
112   @param  Operand The 64-bit operand to rotate left.
113   @param  Count   The number of bits to rotate left.
114 
115   @return Operand <<< Count
116 
117 **/
118 UINT64
119 EFIAPI
120 InternalMathLRotU64 (
121   IN      UINT64                    Operand,
122   IN      UINTN                     Count
123   );
124 
125 /**
126   Rotates a 64-bit integer right between 0 and 63 bits, filling
127   the high bits with the high low bits that were rotated.
128 
129   This function rotates the 64-bit value Operand to the right by Count bits.
130   The high Count bits are fill with the low Count bits of Operand. The rotated
131   value is returned.
132 
133   @param  Operand The 64-bit operand to rotate right.
134   @param  Count   The number of bits to rotate right.
135 
136   @return Operand >>> Count
137 
138 **/
139 UINT64
140 EFIAPI
141 InternalMathRRotU64 (
142   IN      UINT64                    Operand,
143   IN      UINTN                     Count
144   );
145 
146 /**
147   Switches the endianess of a 64-bit integer.
148 
149   This function swaps the bytes in a 64-bit unsigned value to switch the value
150   from little endian to big endian or vice versa. The byte swapped value is
151   returned.
152 
153   @param  Operand A 64-bit unsigned value.
154 
155   @return The byte swaped Operand.
156 
157 **/
158 UINT64
159 EFIAPI
160 InternalMathSwapBytes64 (
161   IN      UINT64                    Operand
162   );
163 
164 /**
165   Multiples a 64-bit unsigned integer by a 32-bit unsigned integer
166   and generates a 64-bit unsigned result.
167 
168   This function multiples the 64-bit unsigned value Multiplicand by the 32-bit
169   unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
170   bit unsigned result is returned.
171 
172   @param  Multiplicand  A 64-bit unsigned value.
173   @param  Multiplier    A 32-bit unsigned value.
174 
175   @return Multiplicand * Multiplier
176 
177 **/
178 UINT64
179 EFIAPI
180 InternalMathMultU64x32 (
181   IN      UINT64                    Multiplicand,
182   IN      UINT32                    Multiplier
183   );
184 
185 /**
186   Multiples a 64-bit unsigned integer by a 64-bit unsigned integer
187   and generates a 64-bit unsigned result.
188 
189   This function multiples the 64-bit unsigned value Multiplicand by the 64-bit
190   unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
191   bit unsigned result is returned.
192 
193   @param  Multiplicand  A 64-bit unsigned value.
194   @param  Multiplier    A 64-bit unsigned value.
195 
196   @return Multiplicand * Multiplier
197 
198 **/
199 UINT64
200 EFIAPI
201 InternalMathMultU64x64 (
202   IN      UINT64                    Multiplicand,
203   IN      UINT64                    Multiplier
204   );
205 
206 /**
207   Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
208   generates a 64-bit unsigned result.
209 
210   This function divides the 64-bit unsigned value Dividend by the 32-bit
211   unsigned value Divisor and generates a 64-bit unsigned quotient. This
212   function returns the 64-bit unsigned quotient.
213 
214    @param  Dividend  A 64-bit unsigned value.
215   @param  Divisor   A 32-bit unsigned value.
216 
217   @return Dividend / Divisor
218 
219 **/
220 UINT64
221 EFIAPI
222 InternalMathDivU64x32 (
223   IN      UINT64                    Dividend,
224   IN      UINT32                    Divisor
225   );
226 
227 /**
228   Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
229   generates a 32-bit unsigned remainder.
230 
231   This function divides the 64-bit unsigned value Dividend by the 32-bit
232   unsigned value Divisor and generates a 32-bit remainder. This function
233   returns the 32-bit unsigned remainder.
234 
235   @param  Dividend  A 64-bit unsigned value.
236   @param  Divisor   A 32-bit unsigned value.
237 
238   @return Dividend % Divisor
239 
240 **/
241 UINT32
242 EFIAPI
243 InternalMathModU64x32 (
244   IN      UINT64                    Dividend,
245   IN      UINT32                    Divisor
246   );
247 
248 /**
249   Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
250   generates a 64-bit unsigned result and an optional 32-bit unsigned remainder.
251 
252   This function divides the 64-bit unsigned value Dividend by the 32-bit
253   unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
254   is not NULL, then the 32-bit unsigned remainder is returned in Remainder.
255   This function returns the 64-bit unsigned quotient.
256 
257   @param  Dividend  A 64-bit unsigned value.
258   @param  Divisor   A 32-bit unsigned value.
259   @param  Remainder A pointer to a 32-bit unsigned value. This parameter is
260                     optional and may be NULL.
261 
262   @return Dividend / Divisor
263 
264 **/
265 UINT64
266 EFIAPI
267 InternalMathDivRemU64x32 (
268   IN      UINT64                    Dividend,
269   IN      UINT32                    Divisor,
270   OUT     UINT32                    *Remainder
271   );
272 
273 /**
274   Divides a 64-bit unsigned integer by a 64-bit unsigned integer and
275   generates a 64-bit unsigned result and an optional 64-bit unsigned remainder.
276 
277   This function divides the 64-bit unsigned value Dividend by the 64-bit
278   unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
279   is not NULL, then the 64-bit unsigned remainder is returned in Remainder.
280   This function returns the 64-bit unsigned quotient.
281 
282   @param  Dividend  A 64-bit unsigned value.
283   @param  Divisor   A 64-bit unsigned value.
284   @param  Remainder A pointer to a 64-bit unsigned value. This parameter is
285                     optional and may be NULL.
286 
287   @return Dividend / Divisor
288 
289 **/
290 UINT64
291 EFIAPI
292 InternalMathDivRemU64x64 (
293   IN      UINT64                    Dividend,
294   IN      UINT64                    Divisor,
295   OUT     UINT64                    *Remainder
296   );
297 
298 /**
299   Divides a 64-bit signed integer by a 64-bit signed integer and
300   generates a  64-bit signed result and a optional 64-bit signed remainder.
301 
302   This function divides the 64-bit unsigned value Dividend by the 64-bit
303   unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
304   is not NULL, then the 64-bit unsigned remainder is returned in Remainder.
305   This function returns the 64-bit unsigned quotient.
306 
307   @param  Dividend  A 64-bit signed value.
308   @param  Divisor   A 64-bit signed value.
309   @param  Remainder A pointer to a 64-bit signed value. This parameter is
310                     optional and may be NULL.
311 
312   @return Dividend / Divisor
313 
314 **/
315 INT64
316 InternalMathDivRemS64x64 (
317   IN      INT64                     Dividend,
318   IN      INT64                     Divisor,
319   OUT     INT64                     *Remainder  OPTIONAL
320  );
321 
322 /**
323   Transfers control to a function starting with a new stack.
324 
325   Transfers control to the function specified by EntryPoint using the
326   new stack specified by NewStack and passing in the parameters specified
327   by Context1 and Context2.  Context1 and Context2 are optional and may
328   be NULL.  The function EntryPoint must never return.
329   Marker will be ignored on IA-32, x64, and EBC.
330   IPF CPUs expect one additional parameter of type VOID * that specifies
331   the new backing store pointer.
332 
333   If EntryPoint is NULL, then ASSERT().
334   If NewStack is NULL, then ASSERT().
335 
336   @param  EntryPoint  A pointer to function to call with the new stack.
337   @param  Context1    A pointer to the context to pass into the EntryPoint
338                       function.
339   @param  Context2    A pointer to the context to pass into the EntryPoint
340                       function.
341   @param  NewStack    A pointer to the new stack to use for the EntryPoint
342                       function.
343   @param  Marker      VA_LIST marker for the variable argument list.
344 
345 **/
346 VOID
347 EFIAPI
348 InternalSwitchStack (
349   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
350   IN      VOID                      *Context1,   OPTIONAL
351   IN      VOID                      *Context2,   OPTIONAL
352   IN      VOID                      *NewStack,
353   IN      VA_LIST                   Marker
354   );
355 
356 
357 /**
358   Worker function that locates the Node in the List
359 
360   By searching the List, finds the location of the Node in List. At the same time,
361   verifies the validity of this list.
362 
363   If List is NULL, then ASSERT().
364   If List->ForwardLink is NULL, then ASSERT().
365   If List->backLink is NULL, then ASSERT().
366   If Node is NULL, then ASSERT();
367   If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
368   of nodes in ListHead, including the ListHead node, is greater than or
369   equal to PcdMaximumLinkedListLength, then ASSERT().
370 
371   @param  List  A pointer to a node in a linked list.
372   @param  Node  A pointer to one nod.
373 
374   @retval TRUE   Node is in List
375   @retval FALSE  Node isn't in List, or List is invalid
376 
377 **/
378 BOOLEAN
379 IsNodeInList (
380   IN      CONST LIST_ENTRY      *List,
381   IN      CONST LIST_ENTRY      *Node
382   );
383 
384 
385 /**
386   Performs an atomic increment of an 32-bit unsigned integer.
387 
388   Performs an atomic increment of the 32-bit unsigned integer specified by
389   Value and returns the incremented value. The increment operation must be
390   performed using MP safe mechanisms. The state of the return value is not
391   guaranteed to be MP safe.
392 
393   @param  Value A pointer to the 32-bit value to increment.
394 
395   @return The incremented value.
396 
397 **/
398 UINT32
399 EFIAPI
400 InternalSyncIncrement (
401   IN      volatile UINT32           *Value
402   );
403 
404 
405 /**
406   Performs an atomic decrement of an 32-bit unsigned integer.
407 
408   Performs an atomic decrement of the 32-bit unsigned integer specified by
409   Value and returns the decrement value. The decrement operation must be
410   performed using MP safe mechanisms. The state of the return value is not
411   guaranteed to be MP safe.
412 
413   @param  Value A pointer to the 32-bit value to decrement.
414 
415   @return The decrement value.
416 
417 **/
418 UINT32
419 EFIAPI
420 InternalSyncDecrement (
421   IN      volatile UINT32           *Value
422   );
423 
424 
425 /**
426   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
427 
428   Performs an atomic compare exchange operation on the 32-bit unsigned integer
429   specified by Value.  If Value is equal to CompareValue, then Value is set to
430   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
431   then Value is returned.  The compare exchange operation must be performed using
432   MP safe mechanisms.
433 
434   @param  Value         A pointer to the 32-bit value for the compare exchange
435                         operation.
436   @param  CompareValue  32-bit value used in compare operation.
437   @param  ExchangeValue 32-bit value used in exchange operation.
438 
439   @return The original *Value before exchange.
440 
441 **/
442 UINT32
443 EFIAPI
444 InternalSyncCompareExchange32 (
445   IN      volatile UINT32           *Value,
446   IN      UINT32                    CompareValue,
447   IN      UINT32                    ExchangeValue
448   );
449 
450 
451 /**
452   Performs an atomic compare exchange operation on a 64-bit unsigned integer.
453 
454   Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
455   by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and
456   CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.
457   The compare exchange operation must be performed using MP safe mechanisms.
458 
459   @param  Value         A pointer to the 64-bit value for the compare exchange
460                         operation.
461   @param  CompareValue  64-bit value used in compare operation.
462   @param  ExchangeValue 64-bit value used in exchange operation.
463 
464   @return The original *Value before exchange.
465 
466 **/
467 UINT64
468 EFIAPI
469 InternalSyncCompareExchange64 (
470   IN      volatile UINT64           *Value,
471   IN      UINT64                    CompareValue,
472   IN      UINT64                    ExchangeValue
473   );
474 
475 
476 /**
477   Worker function that returns a bit field from Operand
478 
479   Returns the bitfield specified by the StartBit and the EndBit from Operand.
480 
481   @param  Operand   Operand on which to perform the bitfield operation.
482   @param  StartBit  The ordinal of the least significant bit in the bit field.
483   @param  EndBit    The ordinal of the most significant bit in the bit field.
484 
485   @return The bit field read.
486 
487 **/
488 unsigned int
489 BitFieldReadUint (
490   IN      unsigned int              Operand,
491   IN      UINTN                     StartBit,
492   IN      UINTN                     EndBit
493   );
494 
495 
496 /**
497   Worker function that reads a bit field from Operand, performs a bitwise OR,
498   and returns the result.
499 
500   Performs a bitwise OR between the bit field specified by StartBit and EndBit
501   in Operand and the value specified by AndData. All other bits in Operand are
502   preserved. The new value is returned.
503 
504   @param  Operand   Operand on which to perform the bitfield operation.
505   @param  StartBit  The ordinal of the least significant bit in the bit field.
506   @param  EndBit    The ordinal of the most significant bit in the bit field.
507   @param  OrData    The value to OR with the read value from the value
508 
509   @return The new value.
510 
511 **/
512 unsigned int
513 BitFieldOrUint (
514   IN      unsigned int              Operand,
515   IN      UINTN                     StartBit,
516   IN      UINTN                     EndBit,
517   IN      unsigned int              OrData
518   );
519 
520 
521 /**
522   Worker function that reads a bit field from Operand, performs a bitwise AND,
523   and returns the result.
524 
525   Performs a bitwise AND between the bit field specified by StartBit and EndBit
526   in Operand and the value specified by AndData. All other bits in Operand are
527   preserved. The new value is returned.
528 
529   @param  Operand   Operand on which to perform the bitfield operation.
530   @param  StartBit  The ordinal of the least significant bit in the bit field.
531   @param  EndBit    The ordinal of the most significant bit in the bit field.
532   @param  AndData    The value to And with the read value from the value
533 
534   @return The new value.
535 
536 **/
537 unsigned int
538 BitFieldAndUint (
539   IN      unsigned int              Operand,
540   IN      UINTN                     StartBit,
541   IN      UINTN                     EndBit,
542   IN      unsigned int              AndData
543   );
544 
545 
546 /**
547   Worker function that checks ASSERT condition for JumpBuffer
548 
549   Checks ASSERT condition for JumpBuffer.
550 
551   If JumpBuffer is NULL, then ASSERT().
552   For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().
553 
554   @param  JumpBuffer    A pointer to CPU context buffer.
555 
556 **/
557 VOID
558 EFIAPI
559 InternalAssertJumpBuffer (
560   IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer
561   );
562 
563 
564 /**
565   Restores the CPU context that was saved with SetJump().
566 
567   Restores the CPU context from the buffer specified by JumpBuffer.
568   This function never returns to the caller.
569   Instead is resumes execution based on the state of JumpBuffer.
570 
571   @param  JumpBuffer    A pointer to CPU context buffer.
572   @param  Value         The value to return when the SetJump() context is restored.
573 
574 **/
575 VOID
576 EFIAPI
577 InternalLongJump (
578   IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,
579   IN      UINTN                     Value
580   );
581 
582 
583 //
584 // Ia32 and x64 specific functions
585 //
586 #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
587 
588 /**
589   Reads the current Global Descriptor Table Register(GDTR) descriptor.
590 
591   Reads and returns the current GDTR descriptor and returns it in Gdtr. This
592   function is only available on IA-32 and X64.
593 
594   @param  Gdtr  Pointer to a GDTR descriptor.
595 
596 **/
597 VOID
598 EFIAPI
599 InternalX86ReadGdtr (
600   OUT     IA32_DESCRIPTOR           *Gdtr
601   );
602 
603 /**
604   Writes the current Global Descriptor Table Register (GDTR) descriptor.
605 
606   Writes and the current GDTR descriptor specified by Gdtr. This function is
607   only available on IA-32 and X64.
608 
609   @param  Gdtr  Pointer to a GDTR descriptor.
610 
611 **/
612 VOID
613 EFIAPI
614 InternalX86WriteGdtr (
615   IN      CONST IA32_DESCRIPTOR     *Gdtr
616   );
617 
618 /**
619   Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
620 
621   Reads and returns the current IDTR descriptor and returns it in Idtr. This
622   function is only available on IA-32 and X64.
623 
624   @param  Idtr  Pointer to a IDTR descriptor.
625 
626 **/
627 VOID
628 EFIAPI
629 InternalX86ReadIdtr (
630   OUT     IA32_DESCRIPTOR           *Idtr
631   );
632 
633 /**
634   Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
635 
636   Writes the current IDTR descriptor and returns it in Idtr. This function is
637   only available on IA-32 and X64.
638 
639   @param  Idtr  Pointer to a IDTR descriptor.
640 
641 **/
642 VOID
643 EFIAPI
644 InternalX86WriteIdtr (
645   IN      CONST IA32_DESCRIPTOR     *Idtr
646   );
647 
648 /**
649   Save the current floating point/SSE/SSE2 context to a buffer.
650 
651   Saves the current floating point/SSE/SSE2 state to the buffer specified by
652   Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
653   available on IA-32 and X64.
654 
655   @param  Buffer  Pointer to a buffer to save the floating point/SSE/SSE2 context.
656 
657 **/
658 VOID
659 EFIAPI
660 InternalX86FxSave (
661   OUT     IA32_FX_BUFFER            *Buffer
662   );
663 
664 /**
665   Restores the current floating point/SSE/SSE2 context from a buffer.
666 
667   Restores the current floating point/SSE/SSE2 state from the buffer specified
668   by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
669   only available on IA-32 and X64.
670 
671   @param  Buffer  Pointer to a buffer to save the floating point/SSE/SSE2 context.
672 
673 **/
674 VOID
675 EFIAPI
676 InternalX86FxRestore (
677   IN      CONST IA32_FX_BUFFER      *Buffer
678   );
679 
680 /**
681   Enables the 32-bit paging mode on the CPU.
682 
683   Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables
684   must be properly initialized prior to calling this service. This function
685   assumes the current execution mode is 32-bit protected mode. This function is
686   only available on IA-32. After the 32-bit paging mode is enabled, control is
687   transferred to the function specified by EntryPoint using the new stack
688   specified by NewStack and passing in the parameters specified by Context1 and
689   Context2. Context1 and Context2 are optional and may be NULL. The function
690   EntryPoint must never return.
691 
692   There are a number of constraints that must be followed before calling this
693   function:
694   1)  Interrupts must be disabled.
695   2)  The caller must be in 32-bit protected mode with flat descriptors. This
696       means all descriptors must have a base of 0 and a limit of 4GB.
697   3)  CR0 and CR4 must be compatible with 32-bit protected mode with flat
698       descriptors.
699   4)  CR3 must point to valid page tables that will be used once the transition
700       is complete, and those page tables must guarantee that the pages for this
701       function and the stack are identity mapped.
702 
703   @param  EntryPoint  A pointer to function to call with the new stack after
704                       paging is enabled.
705   @param  Context1    A pointer to the context to pass into the EntryPoint
706                       function as the first parameter after paging is enabled.
707   @param  Context2    A pointer to the context to pass into the EntryPoint
708                       function as the second parameter after paging is enabled.
709   @param  NewStack    A pointer to the new stack to use for the EntryPoint
710                       function after paging is enabled.
711 
712 **/
713 VOID
714 EFIAPI
715 InternalX86EnablePaging32 (
716   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
717   IN      VOID                      *Context1,  OPTIONAL
718   IN      VOID                      *Context2,  OPTIONAL
719   IN      VOID                      *NewStack
720   );
721 
722 /**
723   Disables the 32-bit paging mode on the CPU.
724 
725   Disables the 32-bit paging mode on the CPU and returns to 32-bit protected
726   mode. This function assumes the current execution mode is 32-paged protected
727   mode. This function is only available on IA-32. After the 32-bit paging mode
728   is disabled, control is transferred to the function specified by EntryPoint
729   using the new stack specified by NewStack and passing in the parameters
730   specified by Context1 and Context2. Context1 and Context2 are optional and
731   may be NULL. The function EntryPoint must never return.
732 
733   There are a number of constraints that must be followed before calling this
734   function:
735   1)  Interrupts must be disabled.
736   2)  The caller must be in 32-bit paged mode.
737   3)  CR0, CR3, and CR4 must be compatible with 32-bit paged mode.
738   4)  CR3 must point to valid page tables that guarantee that the pages for
739       this function and the stack are identity mapped.
740 
741   @param  EntryPoint  A pointer to function to call with the new stack after
742                       paging is disabled.
743   @param  Context1    A pointer to the context to pass into the EntryPoint
744                       function as the first parameter after paging is disabled.
745   @param  Context2    A pointer to the context to pass into the EntryPoint
746                       function as the second parameter after paging is
747                       disabled.
748   @param  NewStack    A pointer to the new stack to use for the EntryPoint
749                       function after paging is disabled.
750 
751 **/
752 VOID
753 EFIAPI
754 InternalX86DisablePaging32 (
755   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
756   IN      VOID                      *Context1,  OPTIONAL
757   IN      VOID                      *Context2,  OPTIONAL
758   IN      VOID                      *NewStack
759   );
760 
761 /**
762   Enables the 64-bit paging mode on the CPU.
763 
764   Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables
765   must be properly initialized prior to calling this service. This function
766   assumes the current execution mode is 32-bit protected mode with flat
767   descriptors. This function is only available on IA-32. After the 64-bit
768   paging mode is enabled, control is transferred to the function specified by
769   EntryPoint using the new stack specified by NewStack and passing in the
770   parameters specified by Context1 and Context2. Context1 and Context2 are
771   optional and may be 0. The function EntryPoint must never return.
772 
773   @param  Cs          The 16-bit selector to load in the CS before EntryPoint
774                       is called. The descriptor in the GDT that this selector
775                       references must be setup for long mode.
776   @param  EntryPoint  The 64-bit virtual address of the function to call with
777                       the new stack after paging is enabled.
778   @param  Context1    The 64-bit virtual address of the context to pass into
779                       the EntryPoint function as the first parameter after
780                       paging is enabled.
781   @param  Context2    The 64-bit virtual address of the context to pass into
782                       the EntryPoint function as the second parameter after
783                       paging is enabled.
784   @param  NewStack    The 64-bit virtual address of the new stack to use for
785                       the EntryPoint function after paging is enabled.
786 
787 **/
788 VOID
789 EFIAPI
790 InternalX86EnablePaging64 (
791   IN      UINT16                    Cs,
792   IN      UINT64                    EntryPoint,
793   IN      UINT64                    Context1,  OPTIONAL
794   IN      UINT64                    Context2,  OPTIONAL
795   IN      UINT64                    NewStack
796   );
797 
798 /**
799   Disables the 64-bit paging mode on the CPU.
800 
801   Disables the 64-bit paging mode on the CPU and returns to 32-bit protected
802   mode. This function assumes the current execution mode is 64-paging mode.
803   This function is only available on X64. After the 64-bit paging mode is
804   disabled, control is transferred to the function specified by EntryPoint
805   using the new stack specified by NewStack and passing in the parameters
806   specified by Context1 and Context2. Context1 and Context2 are optional and
807   may be 0. The function EntryPoint must never return.
808 
809   @param  Cs          The 16-bit selector to load in the CS before EntryPoint
810                       is called. The descriptor in the GDT that this selector
811                       references must be setup for 32-bit protected mode.
812   @param  EntryPoint  The 64-bit virtual address of the function to call with
813                       the new stack after paging is disabled.
814   @param  Context1    The 64-bit virtual address of the context to pass into
815                       the EntryPoint function as the first parameter after
816                       paging is disabled.
817   @param  Context2    The 64-bit virtual address of the context to pass into
818                       the EntryPoint function as the second parameter after
819                       paging is disabled.
820   @param  NewStack    The 64-bit virtual address of the new stack to use for
821                       the EntryPoint function after paging is disabled.
822 
823 **/
824 VOID
825 EFIAPI
826 InternalX86DisablePaging64 (
827   IN      UINT16                    Cs,
828   IN      UINT32                    EntryPoint,
829   IN      UINT32                    Context1,  OPTIONAL
830   IN      UINT32                    Context2,  OPTIONAL
831   IN      UINT32                    NewStack
832   );
833 
834 
835 #elif defined (MDE_CPU_IPF)
836 //
837 //
838 // IPF specific functions
839 //
840 
841 /**
842   Transfers control to a function starting with a new stack.
843 
844   Transfers control to the function specified by EntryPoint using the new stack
845   specified by NewStack and passing in the parameters specified by Context1 and
846   Context2. Context1 and Context2 are optional and may be NULL. The function
847   EntryPoint must never return.
848 
849   If EntryPoint is NULL, then ASSERT().
850   If NewStack is NULL, then ASSERT().
851 
852   @param  EntryPoint  A pointer to function to call with the new stack.
853   @param  Context1    A pointer to the context to pass into the EntryPoint
854                       function.
855   @param  Context2    A pointer to the context to pass into the EntryPoint
856                       function.
857   @param  NewStack    A pointer to the new stack to use for the EntryPoint
858                       function.
859   @param  NewBsp      A pointer to the new memory location for RSE backing
860                       store.
861 
862 **/
863 VOID
864 EFIAPI
865 AsmSwitchStackAndBackingStore (
866   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
867   IN      VOID                      *Context1,  OPTIONAL
868   IN      VOID                      *Context2,  OPTIONAL
869   IN      VOID                      *NewStack,
870   IN      VOID                      *NewBsp
871   );
872 #else
873 
874 #endif
875 
876 #endif
877