]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2WrapperPkg / Library / BaseFspWrapperApiLib / X64 / DispatchExecute.c
CommitLineData
cf1d4549 1/** @file\r
86a2f3c4 2 Execute 64-bit code in Long Mode.\r
cf1d4549
JY
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
86a2f3c4 6 Copyright (c) 2014 - 2022, 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
86a2f3c4
TK
15/**\r
16 FSP API functions.\r
17\r
18 @param[in] Param1 The first parameter to pass to 64bit code.\r
19 @param[in] Param2 The second parameter to pass to 64bit code.\r
20\r
21 @return EFI_STATUS.\r
22**/\r
23typedef\r
24EFI_STATUS\r
25(EFIAPI *FSP_FUNCTION)(\r
26 IN VOID *Param1,\r
27 IN VOID *Param2\r
28 );\r
29\r
cf1d4549
JY
30#pragma pack(1)\r
31typedef union {\r
32 struct {\r
7c7184e2
MK
33 UINT32 LimitLow : 16;\r
34 UINT32 BaseLow : 16;\r
35 UINT32 BaseMid : 8;\r
36 UINT32 Type : 4;\r
37 UINT32 System : 1;\r
38 UINT32 Dpl : 2;\r
39 UINT32 Present : 1;\r
40 UINT32 LimitHigh : 4;\r
41 UINT32 Software : 1;\r
42 UINT32 Reserved : 1;\r
43 UINT32 DefaultSize : 1;\r
44 UINT32 Granularity : 1;\r
45 UINT32 BaseHigh : 8;\r
cf1d4549 46 } Bits;\r
7c7184e2 47 UINT64 Uint64;\r
cf1d4549
JY
48} IA32_GDT;\r
49#pragma pack()\r
50\r
7c7184e2
MK
51GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {\r
52 {\r
53 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }\r
54 }, /* 0x0: reserve */\r
55 {\r
56 { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }\r
57 }, /* 0x8: compatibility mode */\r
58 {\r
59 { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0 }\r
60 }, /* 0x10: for long mode */\r
61 {\r
62 { 0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }\r
63 }, /* 0x18: data */\r
64 {\r
65 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }\r
66 }, /* 0x20: reserve */\r
cf1d4549
JY
67};\r
68\r
69//\r
70// IA32 Gdt register\r
71//\r
7c7184e2 72GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {\r
cf1d4549 73 sizeof (mGdtEntries) - 1,\r
7c7184e2
MK
74 (UINTN)mGdtEntries\r
75};\r
cf1d4549
JY
76\r
77/**\r
78 Assembly function 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 @param[in] InternalGdtr The GDT and GDT descriptor used by this library\r
85\r
86 @return status.\r
87**/\r
88UINT32\r
14a6beac 89EFIAPI\r
cf1d4549
JY
90AsmExecute32BitCode (\r
91 IN UINT64 Function,\r
92 IN UINT64 Param1,\r
93 IN UINT64 Param2,\r
94 IN IA32_DESCRIPTOR *InternalGdtr\r
95 );\r
96\r
97/**\r
86a2f3c4 98 Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
cf1d4549
JY
99 long mode.\r
100\r
101 @param[in] Function The 32bit code entry to be executed.\r
102 @param[in] Param1 The first parameter to pass to 32bit code.\r
103 @param[in] Param2 The second parameter to pass to 32bit code.\r
104\r
105 @return EFI_STATUS.\r
106**/\r
107EFI_STATUS\r
108Execute32BitCode (\r
7c7184e2
MK
109 IN UINT64 Function,\r
110 IN UINT64 Param1,\r
111 IN UINT64 Param2\r
cf1d4549
JY
112 )\r
113{\r
114 EFI_STATUS Status;\r
115 IA32_DESCRIPTOR Idtr;\r
116\r
117 //\r
118 // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address.\r
119 // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only.\r
120 // Interrupt is already disabled here, so it is safety to update IDTR.\r
121 //\r
122 AsmReadIdtr (&Idtr);\r
123 Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);\r
24eac4ca
CC
124 //\r
125 // Convert FSP Status code from 32bit to 64bit to match caller expectation.\r
126 //\r
127 Status = (Status & ~(BIT31 + BIT30)) | LShiftU64 (Status & (BIT31 + BIT30), 32);\r
cf1d4549
JY
128 AsmWriteIdtr (&Idtr);\r
129\r
130 return Status;\r
131}\r
86a2f3c4
TK
132\r
133/**\r
134 Wrapper to execute 64-bit code directly from long mode.\r
135\r
136 @param[in] Function The 64bit code entry to be executed.\r
137 @param[in] Param1 The first parameter to pass to 64bit code.\r
138 @param[in] Param2 The second parameter to pass to 64bit code.\r
139\r
140 @return EFI_STATUS.\r
141**/\r
142EFI_STATUS\r
143Execute64BitCode (\r
144 IN UINT64 Function,\r
145 IN UINT64 Param1,\r
146 IN UINT64 Param2\r
147 )\r
148{\r
149 FSP_FUNCTION EntryFunc;\r
150 EFI_STATUS Status;\r
151\r
152 EntryFunc = (FSP_FUNCTION)(UINTN)(Function);\r
153 Status = EntryFunc ((VOID *)(UINTN)Param1, (VOID *)(UINTN)Param2);\r
154\r
155 return Status;\r
156}\r