2 Declaration of internal functions in BaseLib.
4 Copyright (c) 2006 - 2007, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 Module Name: BaseLibInternals.h
17 #ifndef __BASE_LIB_INTERNALS__
18 #define __BASE_LIB_INTERNALS__
21 // Include common header file for this module.
23 #include "CommonHeader.h"
25 #define QUIENT_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 / 10)
26 #define REMINDER_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 % 10)
28 #define QUIENT_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 / 16)
29 #define REMINDER_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 % 16)
31 #define QUIENT_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 / 10)
32 #define REMINDER_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 % 10)
34 #define QUIENT_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 / 16)
35 #define REMINDER_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 % 16)
42 Shifts a 64-bit integer left between 0 and 63 bits. The low bits
43 are filled with zeros. The shifted value is returned.
45 This function shifts the 64-bit value Operand to the left by Count bits. The
46 low Count bits are set to zero. The shifted value is returned.
48 @param Operand The 64-bit operand to shift left.
49 @param Count The number of bits to shift left.
51 @return Operand << Count
56 InternalMathLShiftU64 (
62 Shifts a 64-bit integer right between 0 and 63 bits. This high bits
63 are filled with zeros. The shifted value is returned.
65 This function shifts the 64-bit value Operand to the right by Count bits. The
66 high Count bits are set to zero. The shifted value is returned.
68 @param Operand The 64-bit operand to shift right.
69 @param Count The number of bits to shift right.
71 @return Operand >> Count
76 InternalMathRShiftU64 (
82 Shifts a 64-bit integer right between 0 and 63 bits. The high bits
83 are filled with original integer's bit 63. The shifted value is returned.
85 This function shifts the 64-bit value Operand to the right by Count bits. The
86 high Count bits are set to bit 63 of Operand. The shifted value is returned.
88 @param Operand The 64-bit operand to shift right.
89 @param Count The number of bits to shift right.
91 @return Operand arithmetically shifted right by Count
96 InternalMathARShiftU64 (
102 Rotates a 64-bit integer left between 0 and 63 bits, filling
103 the low bits with the high bits that were rotated.
105 This function rotates the 64-bit value Operand to the left by Count bits. The
106 low Count bits are fill with the high Count bits of Operand. The rotated
109 @param Operand The 64-bit operand to rotate left.
110 @param Count The number of bits to rotate left.
112 @return Operand <<< Count
117 InternalMathLRotU64 (
123 Rotates a 64-bit integer right between 0 and 63 bits, filling
124 the high bits with the high low bits that were rotated.
126 This function rotates the 64-bit value Operand to the right by Count bits.
127 The high Count bits are fill with the low Count bits of Operand. The rotated
130 @param Operand The 64-bit operand to rotate right.
131 @param Count The number of bits to rotate right.
133 @return Operand >>> Count
138 InternalMathRRotU64 (
144 Switches the endianess of a 64-bit integer.
146 This function swaps the bytes in a 64-bit unsigned value to switch the value
147 from little endian to big endian or vice versa. The byte swapped value is
150 @param Operand A 64-bit unsigned value.
152 @return The byte swaped Operand.
157 InternalMathSwapBytes64 (
162 Multiples a 64-bit unsigned integer by a 32-bit unsigned integer
163 and generates a 64-bit unsigned result.
165 This function multiples the 64-bit unsigned value Multiplicand by the 32-bit
166 unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
167 bit unsigned result is returned.
169 @param Multiplicand A 64-bit unsigned value.
170 @param Multiplier A 32-bit unsigned value.
172 @return Multiplicand * Multiplier
177 InternalMathMultU64x32 (
178 IN UINT64 Multiplicand
,
183 Multiples a 64-bit unsigned integer by a 64-bit unsigned integer
184 and generates a 64-bit unsigned result.
186 This function multiples the 64-bit unsigned value Multiplicand by the 64-bit
187 unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
188 bit unsigned result is returned.
190 @param Multiplicand A 64-bit unsigned value.
191 @param Multiplier A 64-bit unsigned value.
193 @return Multiplicand * Multiplier
198 InternalMathMultU64x64 (
199 IN UINT64 Multiplicand
,
204 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
205 generates a 64-bit unsigned result.
207 This function divides the 64-bit unsigned value Dividend by the 32-bit
208 unsigned value Divisor and generates a 64-bit unsigned quotient. This
209 function returns the 64-bit unsigned quotient.
211 @param Dividend A 64-bit unsigned value.
212 @param Divisor A 32-bit unsigned value.
214 @return Dividend / Divisor
219 InternalMathDivU64x32 (
225 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
226 generates a 32-bit unsigned remainder.
228 This function divides the 64-bit unsigned value Dividend by the 32-bit
229 unsigned value Divisor and generates a 32-bit remainder. This function
230 returns the 32-bit unsigned remainder.
232 @param Dividend A 64-bit unsigned value.
233 @param Divisor A 32-bit unsigned value.
235 @return Dividend % Divisor
240 InternalMathModU64x32 (
246 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
247 generates a 64-bit unsigned result and an optional 32-bit unsigned remainder.
249 This function divides the 64-bit unsigned value Dividend by the 32-bit
250 unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
251 is not NULL, then the 32-bit unsigned remainder is returned in Remainder.
252 This function returns the 64-bit unsigned quotient.
254 @param Dividend A 64-bit unsigned value.
255 @param Divisor A 32-bit unsigned value.
256 @param Remainder A pointer to a 32-bit unsigned value. This parameter is
257 optional and may be NULL.
259 @return Dividend / Divisor
264 InternalMathDivRemU64x32 (
267 OUT UINT32
*Remainder
271 Divides a 64-bit unsigned integer by a 64-bit unsigned integer and
272 generates a 64-bit unsigned result and an optional 64-bit unsigned remainder.
274 This function divides the 64-bit unsigned value Dividend by the 64-bit
275 unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
276 is not NULL, then the 64-bit unsigned remainder is returned in Remainder.
277 This function returns the 64-bit unsigned quotient.
279 @param Dividend A 64-bit unsigned value.
280 @param Divisor A 64-bit unsigned value.
281 @param Remainder A pointer to a 64-bit unsigned value. This parameter is
282 optional and may be NULL.
284 @return Dividend / Divisor
289 InternalMathDivRemU64x64 (
292 OUT UINT64
*Remainder
296 Divides a 64-bit signed integer by a 64-bit signed integer and
297 generates a 64-bit signed result and a optional 64-bit signed remainder.
299 This function divides the 64-bit unsigned value Dividend by the 64-bit
300 unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
301 is not NULL, then the 64-bit unsigned remainder is returned in Remainder.
302 This function returns the 64-bit unsigned quotient.
304 @param Dividend A 64-bit signed value.
305 @param Divisor A 64-bit signed value.
306 @param Remainder A pointer to a 64-bit signed value. This parameter is
307 optional and may be NULL.
309 @return Dividend / Divisor
313 InternalMathDivRemS64x64 (
316 OUT INT64
*Remainder OPTIONAL
320 Transfers control to a function starting with a new stack.
322 Transfers control to the function specified by EntryPoint using the
323 new stack specified by NewStack and passing in the parameters specified
324 by Context1 and Context2. Context1 and Context2 are optional and may
325 be NULL. The function EntryPoint must never return.
326 Marker will be ignored on IA-32, x64, and EBC.
327 IPF CPUs expect one additional parameter of type VOID * that specifies
328 the new backing store pointer.
330 If EntryPoint is NULL, then ASSERT().
331 If NewStack is NULL, then ASSERT().
333 @param EntryPoint A pointer to function to call with the new stack.
334 @param Context1 A pointer to the context to pass into the EntryPoint
336 @param Context2 A pointer to the context to pass into the EntryPoint
338 @param NewStack A pointer to the new stack to use for the EntryPoint
340 @param Marker VA_LIST marker for the variable argument list.
345 InternalSwitchStack (
346 IN SWITCH_STACK_ENTRY_POINT EntryPoint
,
347 IN VOID
*Context1
, OPTIONAL
348 IN VOID
*Context2
, OPTIONAL
355 Worker function that locates the Node in the List
357 By searching the List, finds the location of the Node in List. At the same time,
358 verifies the validity of this list.
360 If List is NULL, then ASSERT().
361 If List->ForwardLink is NULL, then ASSERT().
362 If List->backLink is NULL, then ASSERT().
363 If Node is NULL, then ASSERT();
364 If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
365 of nodes in ListHead, including the ListHead node, is greater than or
366 equal to PcdMaximumLinkedListLength, then ASSERT().
368 @param List A pointer to a node in a linked list.
369 @param Node A pointer to one nod.
371 @retval TRUE Node is in List
372 @retval FALSE Node isn't in List, or List is invalid
377 IN CONST LIST_ENTRY
*List
,
378 IN CONST LIST_ENTRY
*Node
383 Performs an atomic increment of an 32-bit unsigned integer.
385 Performs an atomic increment of the 32-bit unsigned integer specified by
386 Value and returns the incremented value. The increment operation must be
387 performed using MP safe mechanisms. The state of the return value is not
388 guaranteed to be MP safe.
390 @param Value A pointer to the 32-bit value to increment.
392 @return The incremented value.
397 InternalSyncIncrement (
398 IN
volatile UINT32
*Value
403 Performs an atomic decrement of an 32-bit unsigned integer.
405 Performs an atomic decrement of the 32-bit unsigned integer specified by
406 Value and returns the decrement value. The decrement operation must be
407 performed using MP safe mechanisms. The state of the return value is not
408 guaranteed to be MP safe.
410 @param Value A pointer to the 32-bit value to decrement.
412 @return The decrement value.
417 InternalSyncDecrement (
418 IN
volatile UINT32
*Value
423 Performs an atomic compare exchange operation on a 32-bit unsigned integer.
425 Performs an atomic compare exchange operation on the 32-bit unsigned integer
426 specified by Value. If Value is equal to CompareValue, then Value is set to
427 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
428 then Value is returned. The compare exchange operation must be performed using
431 @param Value A pointer to the 32-bit value for the compare exchange
433 @param CompareValue 32-bit value used in compare operation.
434 @param ExchangeValue 32-bit value used in exchange operation.
436 @return The original *Value before exchange.
441 InternalSyncCompareExchange32 (
442 IN
volatile UINT32
*Value
,
443 IN UINT32 CompareValue
,
444 IN UINT32 ExchangeValue
449 Performs an atomic compare exchange operation on a 64-bit unsigned integer.
451 Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
452 by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
453 CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
454 The compare exchange operation must be performed using MP safe mechanisms.
456 @param Value A pointer to the 64-bit value for the compare exchange
458 @param CompareValue 64-bit value used in compare operation.
459 @param ExchangeValue 64-bit value used in exchange operation.
461 @return The original *Value before exchange.
466 InternalSyncCompareExchange64 (
467 IN
volatile UINT64
*Value
,
468 IN UINT64 CompareValue
,
469 IN UINT64 ExchangeValue
474 Worker function that returns a bit field from Operand
476 Returns the bitfield specified by the StartBit and the EndBit from Operand.
478 @param Operand Operand on which to perform the bitfield operation.
479 @param StartBit The ordinal of the least significant bit in the bit field.
480 @param EndBit The ordinal of the most significant bit in the bit field.
482 @return The bit field read.
487 IN
unsigned int Operand
,
494 Worker function that reads a bit field from Operand, performs a bitwise OR,
495 and returns the result.
497 Performs a bitwise OR between the bit field specified by StartBit and EndBit
498 in Operand and the value specified by AndData. All other bits in Operand are
499 preserved. The new value is returned.
501 @param Operand Operand on which to perform the bitfield operation.
502 @param StartBit The ordinal of the least significant bit in the bit field.
503 @param EndBit The ordinal of the most significant bit in the bit field.
504 @param OrData The value to OR with the read value from the value
506 @return The new value.
511 IN
unsigned int Operand
,
514 IN
unsigned int OrData
519 Worker function that reads a bit field from Operand, performs a bitwise AND,
520 and returns the result.
522 Performs a bitwise AND between the bit field specified by StartBit and EndBit
523 in Operand and the value specified by AndData. All other bits in Operand are
524 preserved. The new value is returned.
526 @param Operand Operand on which to perform the bitfield operation.
527 @param StartBit The ordinal of the least significant bit in the bit field.
528 @param EndBit The ordinal of the most significant bit in the bit field.
529 @param AndData The value to And with the read value from the value
531 @return The new value.
536 IN
unsigned int Operand
,
539 IN
unsigned int AndData
544 Worker function that checks ASSERT condition for JumpBuffer
546 Checks ASSERT condition for JumpBuffer.
548 If JumpBuffer is NULL, then ASSERT().
549 For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().
551 @param JumpBuffer A pointer to CPU context buffer.
555 InternalAssertJumpBuffer (
556 IN BASE_LIBRARY_JUMP_BUFFER
*JumpBuffer
561 Restores the CPU context that was saved with SetJump().
563 Restores the CPU context from the buffer specified by JumpBuffer.
564 This function never returns to the caller.
565 Instead is resumes execution based on the state of JumpBuffer.
567 @param JumpBuffer A pointer to CPU context buffer.
568 @param Value The value to return when the SetJump() context is restored.
574 IN BASE_LIBRARY_JUMP_BUFFER
*JumpBuffer
,
580 // Ia32 and x64 specific functions
582 #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
585 Reads the current Global Descriptor Table Register(GDTR) descriptor.
587 Reads and returns the current GDTR descriptor and returns it in Gdtr. This
588 function is only available on IA-32 and X64.
590 @param Gdtr Pointer to a GDTR descriptor.
595 InternalX86ReadGdtr (
596 OUT IA32_DESCRIPTOR
*Gdtr
600 Writes the current Global Descriptor Table Register (GDTR) descriptor.
602 Writes and the current GDTR descriptor specified by Gdtr. This function is
603 only available on IA-32 and X64.
605 @param Gdtr Pointer to a GDTR descriptor.
610 InternalX86WriteGdtr (
611 IN CONST IA32_DESCRIPTOR
*Gdtr
615 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
617 Reads and returns the current IDTR descriptor and returns it in Idtr. This
618 function is only available on IA-32 and X64.
620 @param Idtr Pointer to a IDTR descriptor.
625 InternalX86ReadIdtr (
626 OUT IA32_DESCRIPTOR
*Idtr
630 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
632 Writes the current IDTR descriptor and returns it in Idtr. This function is
633 only available on IA-32 and X64.
635 @param Idtr Pointer to a IDTR descriptor.
640 InternalX86WriteIdtr (
641 IN CONST IA32_DESCRIPTOR
*Idtr
645 Save the current floating point/SSE/SSE2 context to a buffer.
647 Saves the current floating point/SSE/SSE2 state to the buffer specified by
648 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
649 available on IA-32 and X64.
651 @param Buffer Pointer to a buffer to save the floating point/SSE/SSE2 context.
657 OUT IA32_FX_BUFFER
*Buffer
661 Restores the current floating point/SSE/SSE2 context from a buffer.
663 Restores the current floating point/SSE/SSE2 state from the buffer specified
664 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
665 only available on IA-32 and X64.
667 @param Buffer Pointer to a buffer to save the floating point/SSE/SSE2 context.
672 InternalX86FxRestore (
673 IN CONST IA32_FX_BUFFER
*Buffer
677 Enables the 32-bit paging mode on the CPU.
679 Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables
680 must be properly initialized prior to calling this service. This function
681 assumes the current execution mode is 32-bit protected mode. This function is
682 only available on IA-32. After the 32-bit paging mode is enabled, control is
683 transferred to the function specified by EntryPoint using the new stack
684 specified by NewStack and passing in the parameters specified by Context1 and
685 Context2. Context1 and Context2 are optional and may be NULL. The function
686 EntryPoint must never return.
688 There are a number of constraints that must be followed before calling this
690 1) Interrupts must be disabled.
691 2) The caller must be in 32-bit protected mode with flat descriptors. This
692 means all descriptors must have a base of 0 and a limit of 4GB.
693 3) CR0 and CR4 must be compatible with 32-bit protected mode with flat
695 4) CR3 must point to valid page tables that will be used once the transition
696 is complete, and those page tables must guarantee that the pages for this
697 function and the stack are identity mapped.
699 @param EntryPoint A pointer to function to call with the new stack after
701 @param Context1 A pointer to the context to pass into the EntryPoint
702 function as the first parameter after paging is enabled.
703 @param Context2 A pointer to the context to pass into the EntryPoint
704 function as the second parameter after paging is enabled.
705 @param NewStack A pointer to the new stack to use for the EntryPoint
706 function after paging is enabled.
711 InternalX86EnablePaging32 (
712 IN SWITCH_STACK_ENTRY_POINT EntryPoint
,
713 IN VOID
*Context1
, OPTIONAL
714 IN VOID
*Context2
, OPTIONAL
719 Disables the 32-bit paging mode on the CPU.
721 Disables the 32-bit paging mode on the CPU and returns to 32-bit protected
722 mode. This function assumes the current execution mode is 32-paged protected
723 mode. This function is only available on IA-32. After the 32-bit paging mode
724 is disabled, control is transferred to the function specified by EntryPoint
725 using the new stack specified by NewStack and passing in the parameters
726 specified by Context1 and Context2. Context1 and Context2 are optional and
727 may be NULL. The function EntryPoint must never return.
729 There are a number of constraints that must be followed before calling this
731 1) Interrupts must be disabled.
732 2) The caller must be in 32-bit paged mode.
733 3) CR0, CR3, and CR4 must be compatible with 32-bit paged mode.
734 4) CR3 must point to valid page tables that guarantee that the pages for
735 this function and the stack are identity mapped.
737 @param EntryPoint A pointer to function to call with the new stack after
739 @param Context1 A pointer to the context to pass into the EntryPoint
740 function as the first parameter after paging is disabled.
741 @param Context2 A pointer to the context to pass into the EntryPoint
742 function as the second parameter after paging is
744 @param NewStack A pointer to the new stack to use for the EntryPoint
745 function after paging is disabled.
750 InternalX86DisablePaging32 (
751 IN SWITCH_STACK_ENTRY_POINT EntryPoint
,
752 IN VOID
*Context1
, OPTIONAL
753 IN VOID
*Context2
, OPTIONAL
758 Enables the 64-bit paging mode on the CPU.
760 Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables
761 must be properly initialized prior to calling this service. This function
762 assumes the current execution mode is 32-bit protected mode with flat
763 descriptors. This function is only available on IA-32. After the 64-bit
764 paging mode is enabled, control is transferred to the function specified by
765 EntryPoint using the new stack specified by NewStack and passing in the
766 parameters specified by Context1 and Context2. Context1 and Context2 are
767 optional and may be 0. The function EntryPoint must never return.
769 @param Cs The 16-bit selector to load in the CS before EntryPoint
770 is called. The descriptor in the GDT that this selector
771 references must be setup for long mode.
772 @param EntryPoint The 64-bit virtual address of the function to call with
773 the new stack after paging is enabled.
774 @param Context1 The 64-bit virtual address of the context to pass into
775 the EntryPoint function as the first parameter after
777 @param Context2 The 64-bit virtual address of the context to pass into
778 the EntryPoint function as the second parameter after
780 @param NewStack The 64-bit virtual address of the new stack to use for
781 the EntryPoint function after paging is enabled.
786 InternalX86EnablePaging64 (
788 IN UINT64 EntryPoint
,
789 IN UINT64 Context1
, OPTIONAL
790 IN UINT64 Context2
, OPTIONAL
795 Disables the 64-bit paging mode on the CPU.
797 Disables the 64-bit paging mode on the CPU and returns to 32-bit protected
798 mode. This function assumes the current execution mode is 64-paging mode.
799 This function is only available on X64. After the 64-bit paging mode is
800 disabled, control is transferred to the function specified by EntryPoint
801 using the new stack specified by NewStack and passing in the parameters
802 specified by Context1 and Context2. Context1 and Context2 are optional and
803 may be 0. The function EntryPoint must never return.
805 @param Cs The 16-bit selector to load in the CS before EntryPoint
806 is called. The descriptor in the GDT that this selector
807 references must be setup for 32-bit protected mode.
808 @param EntryPoint The 64-bit virtual address of the function to call with
809 the new stack after paging is disabled.
810 @param Context1 The 64-bit virtual address of the context to pass into
811 the EntryPoint function as the first parameter after
813 @param Context2 The 64-bit virtual address of the context to pass into
814 the EntryPoint function as the second parameter after
816 @param NewStack The 64-bit virtual address of the new stack to use for
817 the EntryPoint function after paging is disabled.
822 InternalX86DisablePaging64 (
824 IN UINT32 EntryPoint
,
825 IN UINT32 Context1
, OPTIONAL
826 IN UINT32 Context2
, OPTIONAL
831 #elif defined (MDE_CPU_IPF)
834 // IPF specific functions
838 Transfers control to a function starting with a new stack.
840 Transfers control to the function specified by EntryPoint using the new stack
841 specified by NewStack and passing in the parameters specified by Context1 and
842 Context2. Context1 and Context2 are optional and may be NULL. The function
843 EntryPoint must never return.
845 If EntryPoint is NULL, then ASSERT().
846 If NewStack is NULL, then ASSERT().
848 @param EntryPoint A pointer to function to call with the new stack.
849 @param Context1 A pointer to the context to pass into the EntryPoint
851 @param Context2 A pointer to the context to pass into the EntryPoint
853 @param NewStack A pointer to the new stack to use for the EntryPoint
855 @param NewBsp A pointer to the new memory location for RSE backing
861 AsmSwitchStackAndBackingStore (
862 IN SWITCH_STACK_ENTRY_POINT EntryPoint
,
863 IN VOID
*Context1
, OPTIONAL
864 IN VOID
*Context2
, OPTIONAL