]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
IntelFsp2WrapperPkg: Apply uncrustify changes
[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
14a6beac 6 Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
512e23a3 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf1d4549
JY
8\r
9**/\r
10\r
11#include <Uefi.h>\r
12#include <Library/BaseLib.h>\r
13#include <FspEas.h>\r
14\r
15#pragma pack(1)\r
16typedef union {\r
17 struct {\r
7c7184e2
MK
18 UINT32 LimitLow : 16;\r
19 UINT32 BaseLow : 16;\r
20 UINT32 BaseMid : 8;\r
21 UINT32 Type : 4;\r
22 UINT32 System : 1;\r
23 UINT32 Dpl : 2;\r
24 UINT32 Present : 1;\r
25 UINT32 LimitHigh : 4;\r
26 UINT32 Software : 1;\r
27 UINT32 Reserved : 1;\r
28 UINT32 DefaultSize : 1;\r
29 UINT32 Granularity : 1;\r
30 UINT32 BaseHigh : 8;\r
cf1d4549 31 } Bits;\r
7c7184e2 32 UINT64 Uint64;\r
cf1d4549
JY
33} IA32_GDT;\r
34#pragma pack()\r
35\r
7c7184e2
MK
36GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {\r
37 {\r
38 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }\r
39 }, /* 0x0: reserve */\r
40 {\r
41 { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }\r
42 }, /* 0x8: compatibility mode */\r
43 {\r
44 { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0 }\r
45 }, /* 0x10: for long mode */\r
46 {\r
47 { 0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }\r
48 }, /* 0x18: data */\r
49 {\r
50 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }\r
51 }, /* 0x20: reserve */\r
cf1d4549
JY
52};\r
53\r
54//\r
55// IA32 Gdt register\r
56//\r
7c7184e2 57GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {\r
cf1d4549 58 sizeof (mGdtEntries) - 1,\r
7c7184e2
MK
59 (UINTN)mGdtEntries\r
60};\r
cf1d4549
JY
61\r
62/**\r
63 Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
64 long mode.\r
65\r
66 @param[in] Function The 32bit code entry to be executed.\r
67 @param[in] Param1 The first parameter to pass to 32bit code\r
68 @param[in] Param2 The second parameter to pass to 32bit code\r
69 @param[in] InternalGdtr The GDT and GDT descriptor used by this library\r
70\r
71 @return status.\r
72**/\r
73UINT32\r
14a6beac 74EFIAPI\r
cf1d4549
JY
75AsmExecute32BitCode (\r
76 IN UINT64 Function,\r
77 IN UINT64 Param1,\r
78 IN UINT64 Param2,\r
79 IN IA32_DESCRIPTOR *InternalGdtr\r
80 );\r
81\r
82/**\r
83 Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
84 long mode.\r
85\r
86 @param[in] Function The 32bit code entry to be executed.\r
87 @param[in] Param1 The first parameter to pass to 32bit code.\r
88 @param[in] Param2 The second parameter to pass to 32bit code.\r
89\r
90 @return EFI_STATUS.\r
91**/\r
92EFI_STATUS\r
93Execute32BitCode (\r
7c7184e2
MK
94 IN UINT64 Function,\r
95 IN UINT64 Param1,\r
96 IN UINT64 Param2\r
cf1d4549
JY
97 )\r
98{\r
99 EFI_STATUS Status;\r
100 IA32_DESCRIPTOR Idtr;\r
101\r
102 //\r
103 // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address.\r
104 // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only.\r
105 // Interrupt is already disabled here, so it is safety to update IDTR.\r
106 //\r
107 AsmReadIdtr (&Idtr);\r
108 Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);\r
109 AsmWriteIdtr (&Idtr);\r
110\r
111 return Status;\r
112}\r