From 4cbd21753299e5c119af283aa49443a47d7a72fb Mon Sep 17 00:00:00 2001 From: bxing Date: Sat, 10 Jun 2006 07:16:11 +0000 Subject: [PATCH] 1. Updated SetJump() and LongJump() for IPF 2. Added assertion for SetJump() for all architectures 3. Added CpuSleep() for IPF git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@464 6f19259b-4bc3-4df7-8a09-765794883524 --- MdePkg/Include/Library/BaseLib.h | 76 ++-- MdePkg/Library/BaseLib/BaseLib.msa | 186 ++++----- MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c | 21 +- MdePkg/Library/BaseLib/Ebc/SwitchStack.c | 2 +- MdePkg/Library/BaseLib/Ia32/LongJump.asm | 6 +- MdePkg/Library/BaseLib/Ia32/SetJump.asm | 11 +- MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c | 33 ++ MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s | 15 +- MdePkg/Library/BaseLib/Ipf/PalCallStatic.s | 7 +- MdePkg/Library/BaseLib/Ipf/longjmp.s | 121 ++++++ MdePkg/Library/BaseLib/Ipf/setjmp.s | 373 ++++--------------- MdePkg/Library/BaseLib/LongJump.c | 24 +- MdePkg/Library/BaseLib/SetJump.c | 28 ++ MdePkg/Library/BaseLib/SwitchStack.c | 4 + MdePkg/Library/BaseLib/X64/CpuIdEx.asm | 64 ++++ MdePkg/Library/BaseLib/X64/LongJump.asm | 4 +- MdePkg/Library/BaseLib/X64/SetJump.asm | 7 + 17 files changed, 511 insertions(+), 471 deletions(-) create mode 100644 MdePkg/Library/BaseLib/Ipf/longjmp.s create mode 100644 MdePkg/Library/BaseLib/SetJump.c create mode 100644 MdePkg/Library/BaseLib/X64/CpuIdEx.asm diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 7fb2e64dfb..e042ccb712 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -45,65 +45,44 @@ typedef struct { // IPF context buffer used by SetJump() and LongJump() // typedef struct { - UINT64 InitialUNAT; - UINT64 AfterSpillUNAT; - UINT64 PFS; - UINT64 BSP; - UINT64 RNAT; - UINT64 Predicates; - UINT64 LoopCount; + UINT64 F2[2]; + UINT64 F3[2]; + UINT64 F4[2]; + UINT64 F5[2]; + UINT64 F16[2]; + UINT64 F17[2]; + UINT64 F18[2]; + UINT64 F19[2]; + UINT64 F20[2]; + UINT64 F21[2]; + UINT64 F22[2]; + UINT64 F23[2]; + UINT64 F24[2]; + UINT64 F25[2]; + UINT64 F26[2]; + UINT64 F27[2]; + UINT64 F28[2]; + UINT64 F29[2]; + UINT64 F30[2]; + UINT64 F31[2]; UINT64 R4; UINT64 R5; UINT64 R6; UINT64 R7; UINT64 SP; - UINT64 F2Low; - UINT64 F2High; - UINT64 F3Low; - UINT64 F3High; - UINT64 F4Low; - UINT64 F4High; - UINT64 F5Low; - UINT64 F5High; - UINT64 F16Low; - UINT64 F16High; - UINT64 F17Low; - UINT64 F17High; - UINT64 F18Low; - UINT64 F18High; - UINT64 F19Low; - UINT64 F19High; - UINT64 F20Low; - UINT64 F20High; - UINT64 F21Low; - UINT64 F21High; - UINT64 F22Low; - UINT64 F22High; - UINT64 F23Low; - UINT64 F23High; - UINT64 F24Low; - UINT64 F24High; - UINT64 F25Low; - UINT64 F25High; - UINT64 F26Low; - UINT64 F26High; - UINT64 F27Low; - UINT64 F27High; - UINT64 F28Low; - UINT64 F28High; - UINT64 F29Low; - UINT64 F29High; - UINT64 F30Low; - UINT64 F30High; - UINT64 F31Low; - UINT64 F31High; - UINT64 FPSR; UINT64 BR0; UINT64 BR1; UINT64 BR2; UINT64 BR3; UINT64 BR4; UINT64 BR5; + UINT64 InitialUNAT; + UINT64 AfterSpillUNAT; + UINT64 PFS; + UINT64 BSP; + UINT64 Predicates; + UINT64 LoopCount; + UINT64 FPSR; } BASE_LIBRARY_JUMP_BUFFER; #elif defined (MDE_CPU_X64) @@ -2866,6 +2845,7 @@ typedef union { // // Byte packed structure for an IDTR, GDTR, LDTR descriptor +/// @bug How to make this structure byte-packed in a compiler independent way? // typedef struct { UINT16 Limit; diff --git a/MdePkg/Library/BaseLib/BaseLib.msa b/MdePkg/Library/BaseLib/BaseLib.msa index 4f50169550..5fc8430422 100644 --- a/MdePkg/Library/BaseLib/BaseLib.msa +++ b/MdePkg/Library/BaseLib/BaseLib.msa @@ -36,6 +36,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. BaseMemoryLib DebugLib TimerLib + PcdLib String.c @@ -65,15 +66,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. RRotU32.c RRotU64.c RShiftU64.c + SetJump.c + LongJump.c SwapBytes16.c SwapBytes32.c SwapBytes64.c + SwitchStack.c x86LowLevel.c x86Thunk.c Unaligned.c - LongJump.c - SwitchStack.c Ia32/Non-existing.c Ia32/InternalSwitchStack.c Ia32/LShiftU64.asm @@ -175,104 +177,102 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Ia32/Thunk16.asm - x86LowLevel.c - x86Thunk.c + X86LowLevel.c + X86Thunk.c Unaligned.c Math64.c - LongJump.c - SwitchStack.c - x64/Non-existing.c - x64/SwitchStack.asm - x64/SetJump.asm - x64/LongJump.asm - x64/CpuId.asm - x64/ReadEflags.asm - x64/ReadMsr32.asm - x64/ReadMsr64.asm - x64/WriteMsr32.asm - x64/WriteMsr64.asm - x64/ReadCr0.asm - x64/ReadCr2.asm - x64/ReadCr3.asm - x64/ReadCr4.asm - x64/WriteCr0.asm - x64/WriteCr2.asm - x64/WriteCr3.asm - x64/WriteCr4.asm - x64/ReadDr0.asm - x64/ReadDr1.asm - x64/ReadDr2.asm - x64/ReadDr3.asm - x64/ReadDr4.asm - x64/ReadDr5.asm - x64/ReadDr6.asm - x64/ReadDr7.asm - x64/WriteDr0.asm - x64/WriteDr1.asm - x64/WriteDr2.asm - x64/WriteDr3.asm - x64/WriteDr4.asm - x64/WriteDr5.asm - x64/WriteDr6.asm - x64/WriteDr7.asm - x64/ReadCs.asm - x64/ReadDs.asm - x64/ReadEs.asm - x64/ReadFs.asm - x64/ReadGs.asm - x64/ReadSs.asm - x64/ReadTr.asm - x64/ReadGdtr.asm - x64/WriteGdtr.asm - x64/ReadIdtr.asm - x64/WriteIdtr.asm - x64/ReadLdtr.asm - x64/WriteLdtr.asm - x64/FxSave.asm - x64/FxRestore.asm - x64/ReadMm0.asm - x64/ReadMm1.asm - x64/ReadMm2.asm - x64/ReadMm3.asm - x64/ReadMm4.asm - x64/ReadMm5.asm - x64/ReadMm6.asm - x64/ReadMm7.asm - x64/WriteMm0.asm - x64/WriteMm1.asm - x64/WriteMm2.asm - x64/WriteMm3.asm - x64/WriteMm4.asm - x64/WriteMm5.asm - x64/WriteMm6.asm - x64/WriteMm7.asm - x64/ReadTsc.asm - x64/ReadPmc.asm - x64/Monitor.asm - x64/Mwait.asm - x64/DisablePaging64.asm - x64/Wbinvd.asm - x64/Invd.asm - x64/FlushCacheLine.asm - x64/InterlockedIncrement.asm - x64/InterlockedDecrement.asm - x64/InterlockedCompareExchange32.asm - x64/InterlockedCompareExchange64.asm - x64/EnableInterrupts.asm - x64/DisableInterrupts.asm - x64/EnableDisableInterrupts.asm - x64/CpuSleep.asm - x64/CpuPause.asm - x64/CpuBreakpoint.asm - x64/CpuFlushTlb.asm - x64/Thunk16.asm + X64/Non-existing.c + X64/SwitchStack.asm + X64/SetJump.asm + X64/LongJump.asm + X64/CpuId.asm + X64/CpuIdEx.asm + X64/ReadEflags.asm + X64/ReadMsr32.asm + X64/ReadMsr64.asm + X64/WriteMsr32.asm + X64/WriteMsr64.asm + X64/ReadCr0.asm + X64/ReadCr2.asm + X64/ReadCr3.asm + X64/ReadCr4.asm + X64/WriteCr0.asm + X64/WriteCr2.asm + X64/WriteCr3.asm + X64/WriteCr4.asm + X64/ReadDr0.asm + X64/ReadDr1.asm + X64/ReadDr2.asm + X64/ReadDr3.asm + X64/ReadDr4.asm + X64/ReadDr5.asm + X64/ReadDr6.asm + X64/ReadDr7.asm + X64/WriteDr0.asm + X64/WriteDr1.asm + X64/WriteDr2.asm + X64/WriteDr3.asm + X64/WriteDr4.asm + X64/WriteDr5.asm + X64/WriteDr6.asm + X64/WriteDr7.asm + X64/ReadCs.asm + X64/ReadDs.asm + X64/ReadEs.asm + X64/ReadFs.asm + X64/ReadGs.asm + X64/ReadSs.asm + X64/ReadTr.asm + X64/ReadGdtr.asm + X64/WriteGdtr.asm + X64/ReadIdtr.asm + X64/WriteIdtr.asm + X64/ReadLdtr.asm + X64/WriteLdtr.asm + X64/FxSave.asm + X64/FxRestore.asm + X64/ReadMm0.asm + X64/ReadMm1.asm + X64/ReadMm2.asm + X64/ReadMm3.asm + X64/ReadMm4.asm + X64/ReadMm5.asm + X64/ReadMm6.asm + X64/ReadMm7.asm + X64/WriteMm0.asm + X64/WriteMm1.asm + X64/WriteMm2.asm + X64/WriteMm3.asm + X64/WriteMm4.asm + X64/WriteMm5.asm + X64/WriteMm6.asm + X64/WriteMm7.asm + X64/ReadTsc.asm + X64/ReadPmc.asm + X64/Monitor.asm + X64/Mwait.asm + X64/DisablePaging64.asm + X64/Wbinvd.asm + X64/Invd.asm + X64/FlushCacheLine.asm + X64/InterlockedIncrement.asm + X64/InterlockedDecrement.asm + X64/InterlockedCompareExchange32.asm + X64/InterlockedCompareExchange64.asm + X64/EnableInterrupts.asm + X64/DisableInterrupts.asm + X64/EnableDisableInterrupts.asm + X64/CpuSleep.asm + X64/CpuPause.asm + X64/CpuBreakpoint.asm + X64/CpuFlushTlb.asm + X64/Thunk16.asm Math64.c - LongJump.c - SwitchStack.c Ipf/PalCallStatic.s Ipf/setjmp.s + Ipf/longjmp.s Ipf/SwitchStack.s Ipf/Unaligned.c Ipf/CpuBreakpoint.c diff --git a/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c b/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c index a2381251f3..ab7716cb94 100644 --- a/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c +++ b/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c @@ -1,5 +1,5 @@ /** @file - Switch Stack functions. + Switch Stack functions. Copyright (c) 2006, Intel Corporation All rights reserved. This program and the accompanying materials @@ -14,27 +14,28 @@ **/ - +VOID +EFIAPI +InternalAssertJumpBuffer ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer + ); UINTN EFIAPI SetJump ( - IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer ) { - ASSERT (JumpBuffer != NULL); - ASSERT (FALSE); + InternalAssertJumpBuffer (JumpBuffer); return 0; } VOID EFIAPI -LongJump ( - IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, - IN UINTN Value +InternalLongJump ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, + IN UINTN Value ) { - ASSERT (JumpBuffer != NULL); - ASSERT (Value != 0); ASSERT (FALSE); } diff --git a/MdePkg/Library/BaseLib/Ebc/SwitchStack.c b/MdePkg/Library/BaseLib/Ebc/SwitchStack.c index 73b8edb1af..8fadd4f384 100644 --- a/MdePkg/Library/BaseLib/Ebc/SwitchStack.c +++ b/MdePkg/Library/BaseLib/Ebc/SwitchStack.c @@ -36,7 +36,7 @@ **/ VOID EFIAPI -SwitchStack ( +InternalSwitchStack ( IN SWITCH_STACK_ENTRY_POINT EntryPoint, IN VOID *Context1, OPTIONAL IN VOID *Context2, OPTIONAL diff --git a/MdePkg/Library/BaseLib/Ia32/LongJump.asm b/MdePkg/Library/BaseLib/Ia32/LongJump.asm index 5b7e21aa4b..b52d890567 100644 --- a/MdePkg/Library/BaseLib/Ia32/LongJump.asm +++ b/MdePkg/Library/BaseLib/Ia32/LongJump.asm @@ -20,10 +20,10 @@ ;------------------------------------------------------------------------------ .386 - .model flat + .model flat,C .code -__LongJump PROC +IntenralLongJump PROC pop eax pop edx pop eax @@ -33,6 +33,6 @@ __LongJump PROC mov ebp, [edx + 12] mov esp, [edx + 16] jmp dword ptr [edx + 20] -__LongJump ENDP +IntenralLongJump ENDP END diff --git a/MdePkg/Library/BaseLib/Ia32/SetJump.asm b/MdePkg/Library/BaseLib/Ia32/SetJump.asm index 41277cd20f..7d8579c9b9 100644 --- a/MdePkg/Library/BaseLib/Ia32/SetJump.asm +++ b/MdePkg/Library/BaseLib/Ia32/SetJump.asm @@ -20,10 +20,15 @@ ;------------------------------------------------------------------------------ .386 - .model flat + .model flat,C .code -_SetJump PROC +InternalAssertJumpBuffer PROTO C + +SetJump PROC + push [esp + 4] + call InternalAssertJumpBuffer + pop ecx pop ecx mov edx, [esp] mov [edx], ebx @@ -34,6 +39,6 @@ _SetJump PROC mov [edx + 20], ecx xor eax, eax jmp ecx -_SetJump ENDP +SetJump ENDP END diff --git a/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c b/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c index 7923e92fa9..478cac8c91 100644 --- a/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c +++ b/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c @@ -19,6 +19,22 @@ #pragma intrinsic (__break) #pragma intrinsic (__mfa) +typedef struct { + UINT64 Status; + UINT64 r9; + UINT64 r10; + UINT64 r11; +} PAL_PROC_RETURN; + +PAL_PROC_RETURN +PalCallStatic ( + IN CONST VOID *PalEntryPoint, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4 + ); + /** Generates a breakpoint on the CPU. @@ -117,3 +133,20 @@ EnableDisableInterrupts ( EnableInterrupts (); DisableInterrupts (); } + +/** + Places the CPU in a sleep state until an interrupt is received. + + Places the CPU in a sleep state until an interrupt is received. If interrupts + are disabled prior to calling this function, then the CPU will be placed in a + sleep state indefinitely. + +**/ +VOID +EFIAPI +CpuSleep ( + VOID + ) +{ + PalCallStatic (NULL, 29, 0, 0, 0); +} diff --git a/MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s b/MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s index 608830496c..c50eeb89f3 100644 --- a/MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s +++ b/MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s @@ -23,20 +23,21 @@ .proc CpuFlushTlb .type CpuFlushTlb, @function CpuFlushTlb:: - alloc loc0 = ar.pfs, 0, 2, 5, 0 + alloc loc0 = ar.pfs, 0, 3, 5, 0 mov out0 = 0 mov out1 = 6 mov out2 = 0 mov out3 = 0 - mov out4 = 0 mov loc1 = b0 - br.call.sptk b0 = PalCallStatic - rsm 1 << 14 // Disable interrupts + mov out4 = 0 + brl.call.sptk b0 = PalCallStatic + mov loc2 = psr // save PSR mov ar.pfs = loc0 extr.u r14 = r10, 32, 32 // r14 <- count1 + rsm 1 << 14 // Disable interrupts extr.u r15 = r11, 32, 32 // r15 <- stride1 extr.u r10 = r10, 0, 32 // r10 <- count2 - mov loc0 = psr + add r10 = -1, r10 extr.u r11 = r11, 0, 32 // r11 <- stride2 br.cond.sptk LoopPredicate LoopOuter: @@ -48,10 +49,10 @@ Loop: br.ctop.sptk Loop add r9 = r15, r9 // r9 += stride1 LoopPredicate: - cmp.ne p6, p7 = r0, r14 // count1 == 0? + cmp.ne p6 = r0, r14 // count1 == 0? add r14 = -1, r14 (p6) br.cond.sptk LoopOuter - mov psr.l = loc0 + mov psr.l = loc2 mov b0 = loc1 br.ret.sptk.many b0 .endp diff --git a/MdePkg/Library/BaseLib/Ipf/PalCallStatic.s b/MdePkg/Library/BaseLib/Ipf/PalCallStatic.s index 7fa68e15f6..686383793d 100644 --- a/MdePkg/Library/BaseLib/Ipf/PalCallStatic.s +++ b/MdePkg/Library/BaseLib/Ipf/PalCallStatic.s @@ -22,7 +22,7 @@ .type PalCallStatic, @function .regstk 5, 0, 0, 0 PalCallStatic:: - cmp.ne p6, p7 = r0, in0 + cmp.eq p6 = r0, in0 mov r31 = in4 mov r8 = ip (p6) mov in0 = ar.k5 @@ -39,8 +39,9 @@ PalCallStatic:: br.cond.sptk b7 PalProcReturn: mov psr.l = in3 - cmp.eq p6, p7 = in0, in1 // in1 == PAL_COPY_PAL? -(p6) cmp.eq p6, p7 = r0, r8 // Status == Success? + cmp.eq p6 = in0, in1 // in1 == PAL_COPY_PAL? +(p6) cmp.eq p6 = r0, r8 // Status == Success? +(p6) add in2 = r9, in2 (p6) mov ar.k5 = in2 mov b0 = in4 br.ret.sptk.many b0 diff --git a/MdePkg/Library/BaseLib/Ipf/longjmp.s b/MdePkg/Library/BaseLib/Ipf/longjmp.s new file mode 100644 index 0000000000..20a0df10f7 --- /dev/null +++ b/MdePkg/Library/BaseLib/Ipf/longjmp.s @@ -0,0 +1,121 @@ +/// @file +/// Contains an implementation of longjmp for the Itanium-based architecture. +/// +/// Copyright (c) 2006, Intel Corporation +/// All rights reserved. This program and the accompanying materials +/// are licensed and made available under the terms and conditions of the BSD License +/// which accompanies this distribution. The full text of the license may be found at +/// http://opensource.org/licenses/bsd-license.php +/// +/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +/// +/// Module Name: longjmp.s +/// +/// + +.auto +.text + +.proc InternalLongJump +.type InternalLongJump, @function +.regstk 2, 0, 0, 0 +InternalLongJump:: + add r10 = 0x10*20 + 8*14, in0 + movl r2 = ~((((1 << 14) - 1) << 16) | 3) + + ld8.nt1 r14 = [r10], -8*2 // BSP, skip PFS + mov r15 = ar.bspstore // BSPSTORE + + ld8.nt1 r17 = [r10], -8 // UNAT after spill + mov r16 = ar.rsc // RSC + cmp.leu p6 = r14, r15 + + ld8.nt1 r18 = [r10], -8 // UNAT + ld8.nt1 r25 = [r10], -8 // b5 + and r2 = r16, r2 + + ldf.fill.nt1 f2 = [in0], 0x10 + ld8.nt1 r24 = [r10], -8 // b4 + mov b5 = r25 + + mov ar.rsc = r2 + ld8.nt1 r23 = [r10], -8 // b3 + mov b4 = r24 + + ldf.fill.nt1 f3 = [in0], 0x10 + mov ar.unat = r17 +(p6) br.spnt.many _skip_flushrs + + flushrs + mov r15 = ar.bsp // New BSPSTORE + +_skip_flushrs: + mov r31 = ar.rnat // RNAT + loadrs + + ldf.fill.nt1 f4 = [in0], 0x10 + ld8.nt1 r22 = [r10], -8 + dep r2 = -1, r14, 3, 6 + + ldf.fill.nt1 f5 = [in0], 0x10 + ld8.nt1 r21 = [r10], -8 + cmp.ltu p6 = r2, r15 + + ld8.nt1 r20 = [r10], -0x10 // skip sp +(p6) ld8.nta r31 = [r2] + mov b3 = r23 + + ldf.fill.nt1 f16 = [in0], 0x10 + ld8.fill.nt1 r7 = [r10], -8 + mov b2 = r22 + + ldf.fill.nt1 f17 = [in0], 0x10 + ld8.fill.nt1 r6 = [r10], -8 + mov b1 = r21 + + ldf.fill.nt1 f18 = [in0], 0x10 + ld8.fill.nt1 r5 = [r10], -8 + mov b0 = r20 + + ldf.fill.nt1 f19 = [in0], 0x10 + ld8.fill.nt1 r4 = [r10], 8*13 + + ldf.fill.nt1 f20 = [in0], 0x10 + ld8.nt1 r19 = [r10], 0x10 // PFS + + ldf.fill.nt1 f21 = [in0], 0x10 + ld8.nt1 r26 = [r10], 8 // Predicate + mov ar.pfs = r19 + + ldf.fill.nt1 f22 = [in0], 0x10 + ld8.nt1 r27 = [r10], 8 // LC + mov pr = r26, -1 + + ldf.fill.nt1 f23 = [in0], 0x10 + ld8.nt1 r28 = [r10], -17*8 - 0x10 + mov ar.lc = r27 + + ldf.fill.nt1 f24 = [in0], 0x10 + ldf.fill.nt1 f25 = [in0], 0x10 + mov r8 = in1 + + ldf.fill.nt1 f26 = [in0], 0x10 + ldf.fill.nt1 f31 = [r10], -0x10 + + ldf.fill.nt1 f27 = [in0], 0x10 + ldf.fill.nt1 f30 = [r10], -0x10 + + ldf.fill.nt1 f28 = [in0] + ldf.fill.nt1 f29 = [r10], 0x10*3 + 8*4 + + ld8.fill.nt1 sp = [r10] + mov ar.unat = r18 + + mov ar.bspstore = r14 + mov ar.rnat = r31 + + invala + mov ar.rsc = r16 + br.ret.sptk b0 +.endp diff --git a/MdePkg/Library/BaseLib/Ipf/setjmp.s b/MdePkg/Library/BaseLib/Ipf/setjmp.s index 1098be8306..ff8c747437 100644 --- a/MdePkg/Library/BaseLib/Ipf/setjmp.s +++ b/MdePkg/Library/BaseLib/Ipf/setjmp.s @@ -1,317 +1,108 @@ /// @file -/// Contains an implementation of setjmp and longjmp for the -/// Itanium-based architecture. +/// Contains an implementation of longjmp for the Itanium-based architecture. /// -/// Copyright (c) 2006, Intel Corporation -/// All rights reserved. This program and the accompanying materials -/// are licensed and made available under the terms and conditions of the BSD License -/// which accompanies this distribution. The full text of the license may be found at -/// http://opensource.org/licenses/bsd-license.php -/// -/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -/// -/// Module Name: setjmp.s +/// Copyright (c) 2006, Intel Corporation +/// All rights reserved. This program and the accompanying materials +/// are licensed and made available under the terms and conditions of the BSD License +/// which accompanies this distribution. The full text of the license may be found at +/// http://opensource.org/licenses/bsd-license.php +/// +/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +/// +/// Module Name: longjmp.s /// /// - .file "setjmp.s" +.auto +.text -#include "asm.h" -#include "ia_64gen.h" +.global InternalAssertJumpBuffer +.type InternalAssertJumpBuffer, @function -/// int SetJump(struct jmp_buffer save) -/// -/// Setup a non-local goto. -/// -/// Description: -/// -/// SetJump stores the current register set in the area pointed to -/// by "save". It returns zero. Subsequent calls to "LongJump" will -/// restore the registers and return non-zero to the same location. -/// -/// On entry, r32 contains the pointer to the jmp_buffer -/// +.proc SetJump +.type SetJump, @function +SetJump:: + alloc loc0 = ar.pfs, 1, 2, 1, 0 + mov loc1 = b0 + mov out0 = in0 -PROCEDURE_ENTRY(SetJump) - // - // Make sure buffer is aligned at 16byte boundary - // - mov r32 = r33 + brl.call.sptk.many b0 = InternalAssertJumpBuffer - add r10 = -0x10,r0 ;; // mask the lower 4 bits - and r32 = r32, r10;; - add r32 = 0x10, r32;; // move to next 16 byte boundary + mov r14 = ar.unat + mov r15 = ar.bsp + add r10 = 0x10*20, in0 - add r10 = J_PREDS, r32 // skip Unats & pfs save area - add r11 = J_BSP, r32 - // - // save immediate context - // - mov r2 = ar.bsp // save backing store pointer - mov r3 = pr // save predicates - ;; - // - // save user Unat register - // - mov r16 = ar.lc // save loop count register - mov r14 = ar.unat // save user Unat register + stf.spill.nta [in0] = f2, 0x10 + st8.spill.nta [r10] = r4, 8 + mov r21 = b1 - st8 [r10] = r3, J_LC-J_PREDS - st8 [r11] = r2, J_R4-J_BSP - ;; - st8 [r10] = r16, J_R5-J_LC - st8 [r32] = r14, J_NATS // Note: Unat at the - // beginning of the save area - mov r15 = ar.pfs - ;; - // - // save preserved general registers & NaT's - // - st8.spill [r11] = r4, J_R6-J_R4 - ;; - st8.spill [r10] = r5, J_R7-J_R5 - ;; - st8.spill [r11] = r6, J_SP-J_R6 - ;; - st8.spill [r10] = r7, J_F3-J_R7 - ;; - st8.spill [r11] = sp, J_F2-J_SP - ;; - // - // save spilled Unat and pfs registers - // - mov r2 = ar.unat // save Unat register after spill - ;; - st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs - ;; - st8 [r32] = r15 // save pfs - // - // save floating registers - // - stf.spill [r11] = f2, J_F4-J_F2 - stf.spill [r10] = f3, J_F5-J_F3 - ;; - stf.spill [r11] = f4, J_F16-J_F4 - stf.spill [r10] = f5, J_F17-J_F5 - ;; - stf.spill [r11] = f16, J_F18-J_F16 - stf.spill [r10] = f17, J_F19-J_F17 - ;; - stf.spill [r11] = f18, J_F20-J_F18 - stf.spill [r10] = f19, J_F21-J_F19 - ;; - stf.spill [r11] = f20, J_F22-J_F20 - stf.spill [r10] = f21, J_F23-J_F21 - ;; - stf.spill [r11] = f22, J_F24-J_F22 - stf.spill [r10] = f23, J_F25-J_F23 - ;; - stf.spill [r11] = f24, J_F26-J_F24 - stf.spill [r10] = f25, J_F27-J_F25 - ;; - stf.spill [r11] = f26, J_F28-J_F26 - stf.spill [r10] = f27, J_F29-J_F27 - ;; - stf.spill [r11] = f28, J_F30-J_F28 - stf.spill [r10] = f29, J_F31-J_F29 - ;; - stf.spill [r11] = f30, J_FPSR-J_F30 - stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr - // - // save FPSR register & branch registers - // - mov r2 = ar.fpsr // save fpsr register - mov r3 = b0 - ;; - st8 [r11] = r2, J_B1-J_FPSR - st8 [r10] = r3, J_B2-J_B0 - mov r2 = b1 - mov r3 = b2 - ;; - st8 [r11] = r2, J_B3-J_B1 - st8 [r10] = r3, J_B4-J_B2 - mov r2 = b3 - mov r3 = b4 - ;; - st8 [r11] = r2, J_B5-J_B3 - st8 [r10] = r3 - mov r2 = b5 - ;; - st8 [r11] = r2 - ;; - // - // return - // - mov r8 = r0 // return 0 from setjmp - mov ar.unat = r14 // restore unat - br.ret.sptk b0 + stf.spill.nta [in0] = f3, 0x10 + st8.spill.nta [r10] = r5, 8 + mov r22 = b2 -PROCEDURE_EXIT(SetJump) + stf.spill.nta [in0] = f4, 0x10 + st8.spill.nta [r10] = r6, 8 + mov r23 = b3 + stf.spill.nta [in0] = f5, 0x10 + st8.spill.nta [r10] = r7, 8 + mov r24 = b4 -// -// void _LongJump(struct jmp_buffer *) -// -// Perform a non-local goto. -// -// Description: -// -// LongJump initializes the register set to the values saved by a -// previous 'SetJump' and jumps to the return location saved by that -// 'SetJump'. This has the effect of unwinding the stack and returning -// for a second time to the 'SetJump'. -// + stf.spill.nta [in0] = f16, 0x10 + st8.spill.nta [r10] = sp, 8 + mov r25 = b5 -PROCEDURE_ENTRY(_LongJump) - // - // Make sure buffer is aligned at 16byte boundary - // - mov r32 = r33 + stf.spill.nta [in0] = f17, 0x10 + st8.nta [r10] = loc1, 8 + mov r16 = pr - add r10 = -0x10,r0 ;; // mask the lower 4 bits - and r32 = r32, r10;; - add r32 = 0x10, r32;; // move to next 16 byte boundary + stf.spill.nta [in0] = f18, 0x10 + st8.nta [r10] = r21, 8 + mov r17 = ar.lc - // - // caching the return value as we do invala in the end - // -/// mov r8 = r33 // return value - mov r8 = 1 // For now return hard coded 1 + stf.spill.nta [in0] = f19, 0x10 + st8.nta [r10] = r22, 8 - // - // get immediate context - // - mov r14 = ar.rsc // get user RSC conf - add r10 = J_PFS, r32 // get address of pfs - add r11 = J_NATS, r32 - ;; - ld8 r15 = [r10], J_BSP-J_PFS // get pfs - ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs - ;; - mov ar.unat = r2 - ;; - ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer - mov ar.rsc = r0 // put RSE in enforced lazy - mov ar.pfs = r15 - ;; - - // - // while returning from longjmp the BSPSTORE and BSP needs to be - // same and discard all the registers allocated after we did - // setjmp. Also, we need to generate the RNAT register since we - // did not flushed the RSE on setjmp. - // - mov r17 = ar.bspstore // get current BSPSTORE - ;; - cmp.ltu p6,p7 = r17, r16 // is it less than BSP of -(p6) br.spnt.few .flush_rse - mov r19 = ar.rnat // get current RNAT - ;; - loadrs // invalidate dirty regs - br.sptk.many .restore_rnat // restore RNAT + stf.spill.nta [in0] = f20, 0x10 + st8.nta [r10] = r23, 8 -.flush_rse: - flushrs - ;; - mov r19 = ar.rnat // get current RNAT - mov r17 = r16 // current BSPSTORE - ;; -.restore_rnat: - // - // check if RNAT is saved between saved BSP and curr BSPSTORE - // - dep r18 = 1,r16,3,6 // get RNAT address - ;; - cmp.ltu p8,p9 = r18, r17 // RNAT saved on RSE - ;; -(p8) ld8 r19 = [r18] // get RNAT from RSE - ;; - mov ar.bspstore = r16 // set new BSPSTORE - ;; - mov ar.rnat = r19 // restore RNAT - mov ar.rsc = r14 // restore RSC conf + stf.spill.nta [in0] = f21, 0x10 + st8.nta [r10] = r24, 8 + stf.spill.nta [in0] = f22, 0x10 + st8.nta [r10] = r25, 8 - ld8 r3 = [r11], J_R4-J_LC // get lc register - ld8 r2 = [r10], J_R5-J_PREDS // get predicates - ;; - mov pr = r2, -1 - mov ar.lc = r3 - // - // restore preserved general registers & NaT's - // - ld8.fill r4 = [r11], J_R6-J_R4 - ;; - ld8.fill r5 = [r10], J_R7-J_R5 - ld8.fill r6 = [r11], J_SP-J_R6 - ;; - ld8.fill r7 = [r10], J_F2-J_R7 - ld8.fill sp = [r11], J_F3-J_SP - ;; - // - // restore floating registers - // - ldf.fill f2 = [r10], J_F4-J_F2 - ldf.fill f3 = [r11], J_F5-J_F3 - ;; - ldf.fill f4 = [r10], J_F16-J_F4 - ldf.fill f5 = [r11], J_F17-J_F5 - ;; - ldf.fill f16 = [r10], J_F18-J_F16 - ldf.fill f17 = [r11], J_F19-J_F17 - ;; - ldf.fill f18 = [r10], J_F20-J_F18 - ldf.fill f19 = [r11], J_F21-J_F19 - ;; - ldf.fill f20 = [r10], J_F22-J_F20 - ldf.fill f21 = [r11], J_F23-J_F21 - ;; - ldf.fill f22 = [r10], J_F24-J_F22 - ldf.fill f23 = [r11], J_F25-J_F23 - ;; - ldf.fill f24 = [r10], J_F26-J_F24 - ldf.fill f25 = [r11], J_F27-J_F25 - ;; - ldf.fill f26 = [r10], J_F28-J_F26 - ldf.fill f27 = [r11], J_F29-J_F27 - ;; - ldf.fill f28 = [r10], J_F30-J_F28 - ldf.fill f29 = [r11], J_F31-J_F29 - ;; - ldf.fill f30 = [r10], J_FPSR-J_F30 - ldf.fill f31 = [r11], J_B0-J_F31 ;; + stf.spill.nta [in0] = f23, 0x10 + mov r18 = ar.unat - // - // restore branch registers and fpsr - // - ld8 r16 = [r10], J_B1-J_FPSR // get fpsr - ld8 r17 = [r11], J_B2-J_B0 // get return pointer - ;; - mov ar.fpsr = r16 - mov b0 = r17 - ld8 r2 = [r10], J_B3-J_B1 - ld8 r3 = [r11], J_B4-J_B2 - ;; - mov b1 = r2 - mov b2 = r3 - ld8 r2 = [r10], J_B5-J_B3 - ld8 r3 = [r11] - ;; - mov b3 = r2 - mov b4 = r3 - ld8 r2 = [r10] - ld8 r21 = [r32] // get user unat - ;; - mov b5 = r2 - mov ar.unat = r21 + stf.spill.nta [in0] = f24, 0x10 + st8.nta [r10] = r14, 8 // UNAT - // - // invalidate ALAT - // - invala ;; + stf.spill.nta [in0] = f25, 0x10 + st8.nta [r10] = r18, 8 // UNAT after spill - br.ret.sptk b0 -PROCEDURE_EXIT(_LongJump) + stf.spill.nta [in0] = f26, 0x10 + st8.nta [r10] = loc0, 8 // PFS + stf.spill.nta [in0] = f27, 0x10 + st8.nta [r10] = r15, 8 // BSP + mov r8 = 0 + stf.spill.nta [in0] = f28, 0x10 + mov r19 = ar.fpsr + + stf.spill.nta [in0] = f29, 0x10 + st8.nta [r10] = r16, 8 // PR + mov ar.pfs = loc0 + + stf.spill.nta [in0] = f30, 0x10 + st8.nta [r10] = r17, 8 // LC + mov b0 = loc1 + + stf.spill.nta [in0] = f31, 0x10 + st8.nta [r10] = r19 // FPSR + + mov ar.unat = r14 + br.ret.sptk b0 +.endp SetJump diff --git a/MdePkg/Library/BaseLib/LongJump.c b/MdePkg/Library/BaseLib/LongJump.c index 07b81155ff..302d4bd232 100644 --- a/MdePkg/Library/BaseLib/LongJump.c +++ b/MdePkg/Library/BaseLib/LongJump.c @@ -1,5 +1,5 @@ /** @file - Long Jump functions. + Long Jump functions. Copyright (c) 2006, Intel Corporation All rights reserved. This program and the accompanying materials @@ -16,9 +16,15 @@ VOID EFIAPI -_LongJump ( - IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, - IN UINTN Value +InternalAssertJumpBuffer ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer + ); + +VOID +EFIAPI +InternalLongJump ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, + IN UINTN Value ); /** @@ -38,12 +44,10 @@ _LongJump ( VOID EFIAPI LongJump ( - IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, - IN UINTN Value + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, + IN UINTN Value ) { - ASSERT (JumpBuffer != NULL); - ASSERT (Value != 0); - - _LongJump (JumpBuffer, Value); + InternalAssertJumpBuffer (JumpBuffer); + InternalLongJump (JumpBuffer, Value); } diff --git a/MdePkg/Library/BaseLib/SetJump.c b/MdePkg/Library/BaseLib/SetJump.c new file mode 100644 index 0000000000..ea70641ec2 --- /dev/null +++ b/MdePkg/Library/BaseLib/SetJump.c @@ -0,0 +1,28 @@ +/** @file + Internal ASSERT () functions for SetJump. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: SetJumpLongJump.c + +**/ + +VOID +EFIAPI +InternalAssertJumpBuffer ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer + ) +{ + ASSERT (JumpBuffer != NULL); + +#ifdef MDE_CPU_IPF + ASSERT (((UINTN)JumpBuffer & 0xf) == 0); +#endif +} diff --git a/MdePkg/Library/BaseLib/SwitchStack.c b/MdePkg/Library/BaseLib/SwitchStack.c index fec3cfaa60..353efa8f6e 100644 --- a/MdePkg/Library/BaseLib/SwitchStack.c +++ b/MdePkg/Library/BaseLib/SwitchStack.c @@ -47,5 +47,9 @@ SwitchStack ( { ASSERT (EntryPoint != NULL && NewStack != NULL); +#ifdef MDE_CPU_IPF + ASSERT (((UINTN)NewStack & 0xf) == 0); +#endif + InternalSwitchStack (EntryPoint, Context1, Context2, NewStack); } diff --git a/MdePkg/Library/BaseLib/X64/CpuIdEx.asm b/MdePkg/Library/BaseLib/X64/CpuIdEx.asm new file mode 100644 index 0000000000..ec5729fbaa --- /dev/null +++ b/MdePkg/Library/BaseLib/X64/CpuIdEx.asm @@ -0,0 +1,64 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; CpuId.Asm +; +; Abstract: +; +; AsmCpuid function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; AsmCpuid ( +; IN UINT32 RegisterInEax, +; IN UINT32 RegisterInEcx, +; OUT UINT32 *RegisterOutEax OPTIONAL, +; OUT UINT32 *RegisterOutEbx OPTIONAL, +; OUT UINT32 *RegisterOutEcx OPTIONAL, +; OUT UINT32 *RegisterOutEdx OPTIONAL +; ) +;------------------------------------------------------------------------------ +AsmCpuidEx PROC USES rbx + mov eax, ecx + mov ecx, edx + push rax ; save Index on stack + cpuid + mov r10, [rsp + 38h] + test r10, r10 + jz @F + mov [r10], ecx +@@: + mov rcx, r8 + jrcxz @F + mov [rcx], eax +@@: + mov rcx, r9 + jrcxz @F + mov [rcx], ebx +@@: + mov rcx, [rsp + 40h] + jrcxz @F + mov [rcx], edx +@@: + pop rax ; restore Index to rax as return value + ret +AsmCpuidEx ENDP + + END diff --git a/MdePkg/Library/BaseLib/X64/LongJump.asm b/MdePkg/Library/BaseLib/X64/LongJump.asm index f913b6a2fa..7d468df674 100644 --- a/MdePkg/Library/BaseLib/X64/LongJump.asm +++ b/MdePkg/Library/BaseLib/X64/LongJump.asm @@ -21,7 +21,7 @@ .code -_LongJump PROC +IntenralLongJump PROC mov rbx, [rcx] mov rsp, [rcx + 8] mov rbp, [rcx + 10h] @@ -33,6 +33,6 @@ _LongJump PROC mov r15, [rcx + 40h] mov rax, rdx jmp qword ptr [rcx + 48h] -_LongJump ENDP +IntenralLongJump ENDP END diff --git a/MdePkg/Library/BaseLib/X64/SetJump.asm b/MdePkg/Library/BaseLib/X64/SetJump.asm index 305e721b8b..148b0cb65e 100644 --- a/MdePkg/Library/BaseLib/X64/SetJump.asm +++ b/MdePkg/Library/BaseLib/X64/SetJump.asm @@ -21,7 +21,14 @@ .code +EXTERNDEF InternalAssertJumpBuffer:PROC + SetJump PROC + push rcx + add rsp, -20h + call InternalAssertJumpBuffer + add rsp, 20h + pop rcx pop rdx mov [rcx], rbx mov [rcx + 8], rsp