VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c

Last change on this file was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 5.2 KB
Line 
1/** @file
2 VarCheckHiiLib Dependency library.
3 It sends HII variable checking data to SMM via the MM Communication protocol.
4 Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6**/
7
8#include <Uefi.h>
9#include <Library/UefiBootServicesTableLib.h>
10#include <Library/DebugLib.h>
11#include <Protocol/MmCommunication.h>
12#include <Guid/PiSmmCommunicationRegionTable.h>
13#include "InternalVarCheckStructure.h"
14#include "VarCheckHiiGen.h"
15#include "VarCheckHii.h"
16#include <Library/UefiLib.h>
17#include <Guid/EventGroup.h>
18
19extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin;
20extern UINTN mVarCheckHiiBinSize;
21EFI_GUID gVarCheckReceivedHiiBinHandlerGuid = VAR_CHECK_RECEIVED_HII_BIN_HANDLER_GUID;
22
23/**
24 Sends HII variable checking data to SMM at the end of DXE phase.
25 This function is triggered by the End of DXE. It locates a memory
26 region for MM communication, prepares the communication buffer with HII variable
27 checking data, and communicates with SMM using the MM Communication protocol.
28
29 @param[in] Event Event whose notification function is being invoked.
30 @param[in] Context The pointer to the notification function's context, which
31 is implementation-dependent.
32**/
33VOID
34EFIAPI
35VarCheckHiiLibSmmEndOfDxeNotify (
36 IN EFI_EVENT Event,
37 IN VOID *Context
38 )
39{
40 EFI_STATUS Status;
41 EFI_MM_COMMUNICATION_PROTOCOL *MmCommunication;
42 EFI_MM_COMMUNICATE_HEADER *CommHeader;
43 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;
44 EFI_MEMORY_DESCRIPTOR *MmCommMemRegion;
45 UINTN CommBufferSize;
46 UINTN Index;
47 VAR_CHECK_HII_VARIABLE_HEADER *VarCheckHiiVariable;
48
49 DEBUG ((DEBUG_INFO, "%a starts.\n", __func__));
50 VarCheckHiiGen ();
51 if ((mVarCheckHiiBinSize == 0) || (mVarCheckHiiBin == NULL)) {
52 DEBUG ((DEBUG_INFO, "%a: mVarCheckHiiBinSize = 0x%x, mVarCheckHiiBin = 0x%x \n", __func__, mVarCheckHiiBinSize, mVarCheckHiiBin));
53 return;
54 }
55
56 //
57 // Retrieve SMM Communication Region Table
58 //
59 Status = EfiGetSystemConfigurationTable (
60 &gEdkiiPiSmmCommunicationRegionTableGuid,
61 (VOID **)&PiSmmCommunicationRegionTable
62 );
63 if (EFI_ERROR (Status)) {
64 DEBUG ((DEBUG_ERROR, "%a: Failed to get PiSmmCommunicationRegionTable - %r\n", __func__, Status));
65 return;
66 }
67
68 ASSERT (PiSmmCommunicationRegionTable != NULL);
69 //
70 // Find a memory region for MM communication
71 //
72 CommBufferSize = 0;
73 MmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);
74 for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
75 if (MmCommMemRegion->Type == EfiConventionalMemory) {
76 CommBufferSize = EFI_PAGES_TO_SIZE ((UINTN)MmCommMemRegion->NumberOfPages);
77 if (CommBufferSize >= (sizeof (EFI_MM_COMMUNICATE_HEADER) + mVarCheckHiiBinSize)) {
78 break;
79 }
80 }
81
82 MmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MmCommMemRegion + PiSmmCommunicationRegionTable->DescriptorSize);
83 }
84
85 if (Index >= PiSmmCommunicationRegionTable->NumberOfEntries) {
86 DEBUG ((DEBUG_ERROR, "%a: Failed to find a suitable memory region for MM communication!\n", __func__));
87 return;
88 }
89
90 //
91 // Prepare the communication buffer
92 //
93 CommHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)MmCommMemRegion->PhysicalStart;
94 CommBufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + mVarCheckHiiBinSize;
95 ZeroMem (CommHeader, CommBufferSize);
96 CopyGuid (&CommHeader->HeaderGuid, &gVarCheckReceivedHiiBinHandlerGuid);
97 CommHeader->MessageLength = mVarCheckHiiBinSize;
98 VarCheckHiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)(CommHeader->Data);
99 CopyMem (VarCheckHiiVariable, mVarCheckHiiBin, mVarCheckHiiBinSize);
100 //
101 // Locate the MM Communication protocol and signal SMI
102 //
103 Status = gBS->LocateProtocol (&gEfiMmCommunicationProtocolGuid, NULL, (VOID **)&MmCommunication);
104
105 if (!EFI_ERROR (Status)) {
106 Status = MmCommunication->Communicate (MmCommunication, CommHeader, &CommBufferSize);
107 DEBUG ((DEBUG_INFO, "%a: Communicate to smm environment = %r\n", __func__, Status));
108 } else {
109 DEBUG ((DEBUG_ERROR, "%a: Failed to locate MmCommunication protocol - %r\n", __func__, Status));
110 return;
111 }
112
113 DEBUG ((DEBUG_INFO, "%a ends.\n", __func__));
114 return;
115}
116
117/**
118 Constructor function of the VarCheckHiiLibMmDependency.
119 @param ImageHandle The firmware allocated handle for the EFI image.
120 @param SystemTable A pointer to the Management mode System Table.
121 @retval EFI_SUCCESS The protocol was successfully installed into the DXE database.
122**/
123EFI_STATUS
124EFIAPI
125VarCheckHiiLibMmDependencyConstructor (
126 IN EFI_HANDLE ImageHandle,
127 IN EFI_SYSTEM_TABLE *SystemTable
128 )
129{
130 EFI_STATUS Status;
131 EFI_EVENT Event;
132
133 DEBUG ((DEBUG_INFO, "%a starts.\n", __func__));
134 Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, VarCheckHiiLibSmmEndOfDxeNotify, NULL, &gEfiEndOfDxeEventGroupGuid, &Event);
135 ASSERT_EFI_ERROR (Status);
136 DEBUG ((DEBUG_INFO, "%a ends.\n", __func__));
137 return Status;
138}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette