2 The X64 entrypoint is used to process capsule in long mode.
4 Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
5 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.
15 #include <Library/DebugLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/CpuExceptionHandlerLib.h>
18 #include <Library/DebugAgentLib.h>
19 #include "CommonHeader.h"
21 #define EXCEPTION_VECTOR_NUMBER 0x22
24 The X64 entrypoint is used to process capsule in long mode then
25 return to 32-bit protected mode.
27 @param EntrypointContext Pointer to the context of long mode.
28 @param ReturnContext Pointer to the context of 32-bit protected mode.
30 @retval This function should never return actually.
36 SWITCH_32_TO_64_CONTEXT
*EntrypointContext
,
37 SWITCH_64_TO_32_CONTEXT
*ReturnContext
41 IA32_DESCRIPTOR Ia32Idtr
;
42 IA32_DESCRIPTOR X64Idtr
;
43 IA32_IDT_GATE_DESCRIPTOR IdtEntryTable
[EXCEPTION_VECTOR_NUMBER
];
46 // Save the IA32 IDT Descriptor
48 AsmReadIdtr ((IA32_DESCRIPTOR
*) &Ia32Idtr
);
51 // Setup X64 IDT table
53 ZeroMem (IdtEntryTable
, sizeof (IA32_IDT_GATE_DESCRIPTOR
) * EXCEPTION_VECTOR_NUMBER
);
54 X64Idtr
.Base
= (UINTN
) IdtEntryTable
;
55 X64Idtr
.Limit
= (UINT16
) (sizeof (IA32_IDT_GATE_DESCRIPTOR
) * EXCEPTION_VECTOR_NUMBER
- 1);
56 AsmWriteIdtr ((IA32_DESCRIPTOR
*) &X64Idtr
);
59 // Setup the default CPU exception handlers
61 Status
= InitializeCpuExceptionHandlers (NULL
);
62 ASSERT_EFI_ERROR (Status
);
65 // Initialize Debug Agent to support source level debug
67 InitializeDebugAgent (DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64
, (VOID
*) &Ia32Idtr
, NULL
);
70 // Call CapsuleDataCoalesce to process capsule.
72 Status
= CapsuleDataCoalesce (
74 (EFI_PHYSICAL_ADDRESS
*) (UINTN
) EntrypointContext
->BlockListAddr
,
75 (VOID
**) (UINTN
) EntrypointContext
->MemoryBase64Ptr
,
76 (UINTN
*) (UINTN
) EntrypointContext
->MemorySize64Ptr
79 ReturnContext
->ReturnStatus
= Status
;
82 // Disable interrupt of Debug timer, since the new IDT table cannot work in long mode
84 SaveAndSetDebugTimerInterrupt (FALSE
);
86 // Restore IA32 IDT table
88 AsmWriteIdtr ((IA32_DESCRIPTOR
*) &Ia32Idtr
);
91 // Finish to coalesce capsule, and return to 32-bit mode.
94 ReturnContext
->ReturnCs
,
95 (UINT32
) ReturnContext
->ReturnEntryPoint
,
96 (UINT32
) (UINTN
) EntrypointContext
,
97 (UINT32
) (UINTN
) ReturnContext
,
98 (UINT32
) (EntrypointContext
->StackBufferBase
+ EntrypointContext
->StackBufferLength
)
102 // Should never be here.