]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/SecCore/SecMain.c
UefiCpuPkg: Update SEC_IDT_TABLE struct
[mirror_edk2.git] / UefiCpuPkg / SecCore / SecMain.c
CommitLineData
1921695e
MK
1/** @file\r
2 C functions in SEC\r
3\r
373c2c5b 4 Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>\r
0acd8697 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1921695e
MK
6\r
7**/\r
8\r
9#include "SecMain.h"\r
10\r
053e878b 11EFI_PEI_TEMPORARY_RAM_DONE_PPI gSecTemporaryRamDonePpi = {\r
1921695e
MK
12 SecTemporaryRamDone\r
13};\r
14\r
15EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { SecPlatformInformation };\r
16\r
053e878b 17EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {\r
f2e70629
SZ
18 {\r
19 //\r
20 // SecPerformance PPI notify descriptor.\r
21 //\r
22 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
23 &gPeiSecPerformancePpiGuid,\r
053e878b 24 (VOID *)(UINTN)SecPerformancePpiCallBack\r
f2e70629 25 },\r
1921695e
MK
26 {\r
27 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
28 &gEfiTemporaryRamDonePpiGuid,\r
29 &gSecTemporaryRamDonePpi\r
30 },\r
31 {\r
32 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
33 &gEfiSecPlatformInformationPpiGuid,\r
34 &mSecPlatformInformationPpi\r
35 }\r
36};\r
37\r
f6ec1dd3
GJ
38/**\r
39 Migrates the Global Descriptor Table (GDT) to permanent memory.\r
40\r
41 @retval EFI_SUCCESS The GDT was migrated successfully.\r
42 @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.\r
43\r
44**/\r
45EFI_STATUS\r
46MigrateGdt (\r
47 VOID\r
48 )\r
49{\r
053e878b
MK
50 EFI_STATUS Status;\r
51 UINTN GdtBufferSize;\r
52 IA32_DESCRIPTOR Gdtr;\r
53 VOID *GdtBuffer;\r
f6ec1dd3 54\r
053e878b 55 AsmReadGdtr ((IA32_DESCRIPTOR *)&Gdtr);\r
f6ec1dd3
GJ
56 GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;\r
57\r
58 Status = PeiServicesAllocatePool (\r
59 GdtBufferSize,\r
60 &GdtBuffer\r
61 );\r
62 ASSERT (GdtBuffer != NULL);\r
63 if (EFI_ERROR (Status)) {\r
64 return EFI_OUT_OF_RESOURCES;\r
65 }\r
66\r
67 GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));\r
053e878b
MK
68 CopyMem (GdtBuffer, (VOID *)Gdtr.Base, Gdtr.Limit + 1);\r
69 Gdtr.Base = (UINTN)GdtBuffer;\r
f6ec1dd3
GJ
70 AsmWriteGdtr (&Gdtr);\r
71\r
72 return EFI_SUCCESS;\r
73}\r
74\r
1921695e
MK
75//\r
76// These are IDT entries pointing to 10:FFFFFFE4h.\r
77//\r
78UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;\r
79\r
80/**\r
81 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
82\r
83 Entry point to the C language phase of SEC. After the SEC assembly\r
84 code has initialized some temporary memory and set up the stack,\r
85 the control is transferred to this function.\r
86\r
87 @param[in] Context The first input parameter of InitializeDebugAgent().\r
88\r
89**/\r
90VOID\r
61257251 91NORETURN\r
1921695e 92EFIAPI\r
053e878b
MK
93SecStartupPhase2 (\r
94 IN VOID *Context\r
1921695e
MK
95 );\r
96\r
f2e70629
SZ
97/**\r
98 Entry point of the notification callback function itself within the PEIM.\r
99 It is to get SEC performance data and build HOB to convey the SEC performance\r
100 data to DXE phase.\r
101\r
102 @param PeiServices Indirect reference to the PEI Services Table.\r
103 @param NotifyDescriptor Address of the notification descriptor data structure.\r
104 @param Ppi Address of the PPI that was installed.\r
105\r
106 @return Status of the notification.\r
107 The status code returned from this function is ignored.\r
108**/\r
109EFI_STATUS\r
110EFIAPI\r
111SecPerformancePpiCallBack (\r
112 IN EFI_PEI_SERVICES **PeiServices,\r
113 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
114 IN VOID *Ppi\r
115 )\r
116{\r
053e878b
MK
117 EFI_STATUS Status;\r
118 PEI_SEC_PERFORMANCE_PPI *SecPerf;\r
119 FIRMWARE_SEC_PERFORMANCE Performance;\r
f2e70629 120\r
053e878b
MK
121 SecPerf = (PEI_SEC_PERFORMANCE_PPI *)Ppi;\r
122 Status = SecPerf->GetPerformance ((CONST EFI_PEI_SERVICES **)PeiServices, SecPerf, &Performance);\r
f2e70629
SZ
123 if (!EFI_ERROR (Status)) {\r
124 BuildGuidDataHob (\r
125 &gEfiFirmwarePerformanceGuid,\r
126 &Performance,\r
127 sizeof (FIRMWARE_SEC_PERFORMANCE)\r
053e878b 128 );\r
f2e70629
SZ
129 DEBUG ((DEBUG_INFO, "FPDT: SEC Performance Hob ResetEnd = %ld\n", Performance.ResetEnd));\r
130 }\r
131\r
132 return Status;\r
133}\r
134\r
1921695e
MK
135/**\r
136\r
137 Entry point to the C language phase of SEC. After the SEC assembly\r
138 code has initialized some temporary memory and set up the stack,\r
139 the control is transferred to this function.\r
140\r
141\r
142 @param SizeOfRam Size of the temporary memory available for use.\r
143 @param TempRamBase Base address of temporary ram\r
144 @param BootFirmwareVolume Base address of the Boot Firmware Volume.\r
145**/\r
146VOID\r
7cd8a575 147NORETURN\r
1921695e
MK
148EFIAPI\r
149SecStartup (\r
053e878b
MK
150 IN UINT32 SizeOfRam,\r
151 IN UINT32 TempRamBase,\r
152 IN VOID *BootFirmwareVolume\r
1921695e
MK
153 )\r
154{\r
053e878b
MK
155 EFI_SEC_PEI_HAND_OFF SecCoreData;\r
156 IA32_DESCRIPTOR IdtDescriptor;\r
157 SEC_IDT_TABLE IdtTableInStack;\r
158 UINT32 Index;\r
159 UINT32 PeiStackSize;\r
160 EFI_STATUS Status;\r
1921695e
MK
161\r
162 //\r
163 // Report Status Code to indicate entering SEC core\r
164 //\r
165 REPORT_STATUS_CODE (\r
166 EFI_PROGRESS_CODE,\r
167 EFI_SOFTWARE_SEC | EFI_SW_SEC_PC_ENTRY_POINT\r
168 );\r
169\r
e93bc630
OI
170 DEBUG ((\r
171 DEBUG_INFO,\r
172 "%a() TempRAM Base: 0x%x, TempRAM Size: 0x%x, BootFirmwareVolume 0x%x\n",\r
173 __FUNCTION__,\r
174 TempRamBase,\r
175 SizeOfRam,\r
176 BootFirmwareVolume\r
177 ));\r
178\r
1921695e
MK
179 PeiStackSize = PcdGet32 (PcdPeiTemporaryRamStackSize);\r
180 if (PeiStackSize == 0) {\r
181 PeiStackSize = (SizeOfRam >> 1);\r
182 }\r
183\r
184 ASSERT (PeiStackSize < SizeOfRam);\r
185\r
186 //\r
187 // Process all libraries constructor function linked to SecCore.\r
188 //\r
189 ProcessLibraryConstructorList ();\r
190\r
191 //\r
192 // Initialize floating point operating environment\r
193 // to be compliant with UEFI spec.\r
194 //\r
195 InitializeFloatingPointUnits ();\r
196\r
197 // |-------------------|---->\r
198 // |IDT Table |\r
199 // |-------------------|\r
200 // |PeiService Pointer | PeiStackSize\r
201 // |-------------------|\r
202 // | |\r
203 // | Stack |\r
204 // |-------------------|---->\r
205 // | |\r
206 // | |\r
207 // | Heap | PeiTemporayRamSize\r
208 // | |\r
209 // | |\r
210 // |-------------------|----> TempRamBase\r
211\r
212 IdtTableInStack.PeiService = 0;\r
053e878b 213 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {\r
9ab389c0 214 ZeroMem ((VOID *)&IdtTableInStack.IdtTable[Index], sizeof (IA32_IDT_GATE_DESCRIPTOR));\r
053e878b 215 CopyMem ((VOID *)&IdtTableInStack.IdtTable[Index], (VOID *)&mIdtEntryTemplate, sizeof (UINT64));\r
1921695e
MK
216 }\r
217\r
053e878b 218 IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;\r
1921695e
MK
219 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
220\r
221 AsmWriteIdtr (&IdtDescriptor);\r
222\r
223 //\r
224 // Setup the default exception handlers\r
225 //\r
226 Status = InitializeCpuExceptionHandlers (NULL);\r
227 ASSERT_EFI_ERROR (Status);\r
228\r
229 //\r
230 // Update the base address and length of Pei temporary memory\r
231 //\r
053e878b 232 SecCoreData.DataSize = (UINT16)sizeof (EFI_SEC_PEI_HAND_OFF);\r
1921695e 233 SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;\r
053e878b
MK
234 SecCoreData.BootFirmwareVolumeSize = (UINTN)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;\r
235 SecCoreData.TemporaryRamBase = (VOID *)(UINTN)TempRamBase;\r
1921695e
MK
236 SecCoreData.TemporaryRamSize = SizeOfRam;\r
237 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
238 SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize;\r
053e878b 239 SecCoreData.StackBase = (VOID *)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);\r
1921695e
MK
240 SecCoreData.StackSize = PeiStackSize;\r
241\r
e93bc630
OI
242 DEBUG ((\r
243 DEBUG_INFO,\r
244 "%a() BFV Base: 0x%x, BFV Size: 0x%x, TempRAM Base: 0x%x, TempRAM Size: 0x%x, PeiTempRamBase: 0x%x, PeiTempRamSize: 0x%x, StackBase: 0x%x, StackSize: 0x%x\n",\r
245 __FUNCTION__,\r
246 SecCoreData.BootFirmwareVolumeBase,\r
247 SecCoreData.BootFirmwareVolumeSize,\r
248 SecCoreData.TemporaryRamBase,\r
249 SecCoreData.TemporaryRamSize,\r
250 SecCoreData.PeiTemporaryRamBase,\r
251 SecCoreData.PeiTemporaryRamSize,\r
252 SecCoreData.StackBase,\r
253 SecCoreData.StackSize\r
254 ));\r
255\r
1921695e
MK
256 //\r
257 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
258 //\r
259 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);\r
7cd8a575
MH
260\r
261 //\r
262 // Should not come here.\r
263 //\r
264 UNREACHABLE ();\r
1921695e
MK
265}\r
266\r
267/**\r
268 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
269\r
270 Entry point to the C language phase of SEC. After the SEC assembly\r
271 code has initialized some temporary memory and set up the stack,\r
272 the control is transferred to this function.\r
273\r
274 @param[in] Context The first input parameter of InitializeDebugAgent().\r
275\r
276**/\r
277VOID\r
61257251 278NORETURN\r
1921695e 279EFIAPI\r
053e878b
MK
280SecStartupPhase2 (\r
281 IN VOID *Context\r
1921695e
MK
282 )\r
283{\r
053e878b
MK
284 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
285 EFI_PEI_PPI_DESCRIPTOR *PpiList;\r
286 UINT32 Index;\r
287 EFI_PEI_PPI_DESCRIPTOR *AllSecPpiList;\r
288 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;\r
1921695e 289\r
373c2c5b 290 PeiCoreEntryPoint = NULL;\r
053e878b 291 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;\r
373c2c5b 292\r
1b261a70
CC
293 //\r
294 // Perform platform specific initialization before entering PeiCore.\r
295 //\r
296 PpiList = SecPlatformMain (SecCoreData);\r
1921695e
MK
297 //\r
298 // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug\r
299 // is enabled.\r
300 //\r
373c2c5b 301 if (PpiList != NULL) {\r
8a1305a1
CC
302 Index = 0;\r
303 do {\r
08283b96 304 if (CompareGuid (PpiList[Index].Guid, &gEfiPeiCoreFvLocationPpiGuid) &&\r
053e878b
MK
305 (((EFI_PEI_CORE_FV_LOCATION_PPI *)PpiList[Index].Ppi)->PeiCoreFvLocation != 0)\r
306 )\r
307 {\r
08283b96
CC
308 //\r
309 // In this case, SecCore is in BFV but PeiCore is in another FV reported by PPI.\r
310 //\r
311 FindAndReportEntryPoints (\r
053e878b
MK
312 (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase,\r
313 (EFI_FIRMWARE_VOLUME_HEADER *)((EFI_PEI_CORE_FV_LOCATION_PPI *)PpiList[Index].Ppi)->PeiCoreFvLocation,\r
08283b96
CC
314 &PeiCoreEntryPoint\r
315 );\r
373c2c5b
CC
316 if (PeiCoreEntryPoint != NULL) {\r
317 break;\r
318 } else {\r
319 //\r
8a1305a1 320 // Invalid PeiCore FV provided by platform\r
373c2c5b
CC
321 //\r
322 CpuDeadLoop ();\r
323 }\r
324 }\r
8a1305a1 325 } while ((PpiList[Index++].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
373c2c5b 326 }\r
053e878b 327\r
373c2c5b
CC
328 //\r
329 // If EFI_PEI_CORE_FV_LOCATION_PPI not found, try to locate PeiCore from BFV.\r
330 //\r
331 if (PeiCoreEntryPoint == NULL) {\r
08283b96
CC
332 //\r
333 // Both SecCore and PeiCore are in BFV.\r
334 //\r
335 FindAndReportEntryPoints (\r
053e878b
MK
336 (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase,\r
337 (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase,\r
08283b96
CC
338 &PeiCoreEntryPoint\r
339 );\r
373c2c5b
CC
340 if (PeiCoreEntryPoint == NULL) {\r
341 CpuDeadLoop ();\r
342 }\r
1921695e
MK
343 }\r
344\r
e93bc630
OI
345 DEBUG ((\r
346 DEBUG_INFO,\r
347 "%a() PeiCoreEntryPoint: 0x%x\n",\r
348 __FUNCTION__,\r
349 PeiCoreEntryPoint\r
350 ));\r
351\r
1921695e 352 if (PpiList != NULL) {\r
053e878b 353 AllSecPpiList = (EFI_PEI_PPI_DESCRIPTOR *)SecCoreData->PeiTemporaryRamBase;\r
47f167f4 354\r
1921695e
MK
355 //\r
356 // Remove the terminal flag from the terminal PPI\r
357 //\r
358 CopyMem (AllSecPpiList, mPeiSecPlatformInformationPpi, sizeof (mPeiSecPlatformInformationPpi));\r
053e878b 359 Index = sizeof (mPeiSecPlatformInformationPpi) / sizeof (EFI_PEI_PPI_DESCRIPTOR) - 1;\r
1921695e
MK
360 AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
361\r
362 //\r
363 // Append the platform additional PPI list\r
364 //\r
365 Index += 1;\r
366 while (((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) {\r
367 CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
368 Index++;\r
369 PpiList++;\r
370 }\r
371\r
372 //\r
373 // Add the terminal PPI\r
374 //\r
053e878b 375 CopyMem (&AllSecPpiList[Index++], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
1921695e
MK
376\r
377 //\r
378 // Set PpiList to the total PPI\r
379 //\r
380 PpiList = AllSecPpiList;\r
381\r
382 //\r
383 // Adjust PEI TEMP RAM Range.\r
384 //\r
385 ASSERT (SecCoreData->PeiTemporaryRamSize > Index * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
053e878b 386 SecCoreData->PeiTemporaryRamBase = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + Index * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
1921695e 387 SecCoreData->PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize - Index * sizeof (EFI_PEI_PPI_DESCRIPTOR);\r
9e9ca210
SZ
388 //\r
389 // Adjust the Base and Size to be 8-byte aligned as HOB which has 8byte aligned requirement\r
390 // will be built based on them in PEI phase.\r
391 //\r
053e878b 392 SecCoreData->PeiTemporaryRamBase = (VOID *)(((UINTN)SecCoreData->PeiTemporaryRamBase + 7) & ~0x07);\r
59d3fad3 393 SecCoreData->PeiTemporaryRamSize &= ~(UINTN)0x07;\r
e93bc630
OI
394 DEBUG ((\r
395 DEBUG_INFO,\r
396 "%a() PeiTemporaryRamBase: 0x%x, PeiTemporaryRamSize: 0x%x\n",\r
397 __FUNCTION__,\r
398 SecCoreData->PeiTemporaryRamBase,\r
399 SecCoreData->PeiTemporaryRamSize\r
400 ));\r
1921695e
MK
401 } else {\r
402 //\r
403 // No addition PPI, PpiList directly point to the common PPI list.\r
404 //\r
405 PpiList = &mPeiSecPlatformInformationPpi[0];\r
406 }\r
407\r
af34c106
JF
408 DEBUG ((\r
409 DEBUG_INFO,\r
ec16deea 410 "%a() Stack Base: 0x%p, Stack Size: 0x%x\n",\r
af34c106
JF
411 __FUNCTION__,\r
412 SecCoreData->StackBase,\r
053e878b 413 (UINT32)SecCoreData->StackSize\r
af34c106
JF
414 ));\r
415\r
1921695e
MK
416 //\r
417 // Report Status Code to indicate transferring to PEI core\r
418 //\r
419 REPORT_STATUS_CODE (\r
420 EFI_PROGRESS_CODE,\r
421 EFI_SOFTWARE_SEC | EFI_SW_SEC_PC_HANDOFF_TO_NEXT\r
422 );\r
423\r
424 //\r
425 // Transfer the control to the PEI core\r
426 //\r
427 ASSERT (PeiCoreEntryPoint != NULL);\r
053e878b 428 (*PeiCoreEntryPoint)(SecCoreData, PpiList);\r
1921695e
MK
429\r
430 //\r
431 // Should not come here.\r
432 //\r
61257251 433 UNREACHABLE ();\r
1921695e
MK
434}\r
435\r
436/**\r
437 TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked\r
438 by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.\r
439\r
440 @retval EFI_SUCCESS Use of Temporary RAM was disabled.\r
441 @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.\r
442\r
443**/\r
444EFI_STATUS\r
445EFIAPI\r
446SecTemporaryRamDone (\r
447 VOID\r
448 )\r
449{\r
053e878b
MK
450 EFI_STATUS Status;\r
451 EFI_STATUS Status2;\r
452 UINTN Index;\r
453 BOOLEAN State;\r
454 EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;\r
455 REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;\r
1921695e 456\r
8a5b8cef
JF
457 //\r
458 // Republish Sec Platform Information(2) PPI\r
459 //\r
460 RepublishSecPlatformInformationPpi ();\r
461\r
479613bd
MK
462 //\r
463 // Re-install SEC PPIs using a PEIM produced service if published\r
464 //\r
465 for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {\r
466 Status = PeiServicesLocatePpi (\r
467 &gRepublishSecPpiPpiGuid,\r
468 Index,\r
469 &PeiPpiDescriptor,\r
053e878b 470 (VOID **)&RepublishSecPpiPpi\r
479613bd
MK
471 );\r
472 if (!EFI_ERROR (Status)) {\r
473 DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));\r
474 Status2 = RepublishSecPpiPpi->RepublishSecPpis ();\r
475 ASSERT_EFI_ERROR (Status2);\r
476 }\r
477 }\r
478\r
1921695e
MK
479 //\r
480 // Migrate DebugAgentContext.\r
481 //\r
482 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);\r
483\r
484 //\r
485 // Disable interrupts and save current interrupt state\r
486 //\r
479613bd 487 State = SaveAndDisableInterrupts ();\r
1921695e 488\r
f6ec1dd3
GJ
489 //\r
490 // Migrate GDT before NEM near down\r
491 //\r
492 if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {\r
493 Status = MigrateGdt ();\r
494 ASSERT_EFI_ERROR (Status);\r
495 }\r
496\r
1921695e
MK
497 //\r
498 // Disable Temporary RAM after Stack and Heap have been migrated at this point.\r
499 //\r
500 SecPlatformDisableTemporaryMemory ();\r
501\r
502 //\r
503 // Restore original interrupt state\r
504 //\r
505 SetInterruptState (State);\r
506\r
507 return EFI_SUCCESS;\r
508}\r