]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
UefiCpuPkg CpuMpPei: Update INF to refer to NASM source file
[mirror_edk2.git] / IntelFsp2WrapperPkg / Library / BaseFspWrapperApiLib / X64 / DispatchExecute.c
CommitLineData
cf1d4549
JY
1/** @file\r
2 Execute 32-bit code in Long Mode.\r
3 Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit\r
4 back to long mode.\r
5\r
6 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
7 This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php.\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <Uefi.h>\r
18#include <Library/BaseLib.h>\r
19#include <FspEas.h>\r
20\r
21#pragma pack(1)\r
22typedef union {\r
23 struct {\r
24 UINT32 LimitLow : 16;\r
25 UINT32 BaseLow : 16;\r
26 UINT32 BaseMid : 8;\r
27 UINT32 Type : 4;\r
28 UINT32 System : 1;\r
29 UINT32 Dpl : 2;\r
30 UINT32 Present : 1;\r
31 UINT32 LimitHigh : 4;\r
32 UINT32 Software : 1;\r
33 UINT32 Reserved : 1;\r
34 UINT32 DefaultSize : 1;\r
35 UINT32 Granularity : 1;\r
36 UINT32 BaseHigh : 8;\r
37 } Bits;\r
38 UINT64 Uint64;\r
39} IA32_GDT;\r
40#pragma pack()\r
41\r
42GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {\r
43 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x0: reserve */\r
44 {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x8: compatibility mode */\r
45 {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0}}, /* 0x10: for long mode */\r
46 {{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x18: data */\r
47 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x20: reserve */\r
48};\r
49\r
50//\r
51// IA32 Gdt register\r
52//\r
53GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {\r
54 sizeof (mGdtEntries) - 1,\r
55 (UINTN) mGdtEntries\r
56 };\r
57\r
58/**\r
59 Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
60 long mode.\r
61\r
62 @param[in] Function The 32bit code entry to be executed.\r
63 @param[in] Param1 The first parameter to pass to 32bit code\r
64 @param[in] Param2 The second parameter to pass to 32bit code\r
65 @param[in] InternalGdtr The GDT and GDT descriptor used by this library\r
66\r
67 @return status.\r
68**/\r
69UINT32\r
70AsmExecute32BitCode (\r
71 IN UINT64 Function,\r
72 IN UINT64 Param1,\r
73 IN UINT64 Param2,\r
74 IN IA32_DESCRIPTOR *InternalGdtr\r
75 );\r
76\r
77/**\r
78 Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
79 long mode.\r
80\r
81 @param[in] Function The 32bit code entry to be executed.\r
82 @param[in] Param1 The first parameter to pass to 32bit code.\r
83 @param[in] Param2 The second parameter to pass to 32bit code.\r
84\r
85 @return EFI_STATUS.\r
86**/\r
87EFI_STATUS\r
88Execute32BitCode (\r
89 IN UINT64 Function,\r
90 IN UINT64 Param1,\r
91 IN UINT64 Param2\r
92 )\r
93{\r
94 EFI_STATUS Status;\r
95 IA32_DESCRIPTOR Idtr;\r
96\r
97 //\r
98 // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address.\r
99 // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only.\r
100 // Interrupt is already disabled here, so it is safety to update IDTR.\r
101 //\r
102 AsmReadIdtr (&Idtr);\r
103 Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);\r
104 AsmWriteIdtr (&Idtr);\r
105\r
106 return Status;\r
107}\r
108\r