1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/** @file
Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/MmCommunication2.h>
#include "NVParamLibCommon.h"
STATIC EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunicationProtocol = NULL;
/**
This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
event. It converts a pointer to a new virtual address.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context
**/
VOID
EFIAPI
NVParamLibAddressChangeEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
gRT->ConvertPointer (0x0, (VOID **)&mMmCommunicationProtocol);
}
/**
Constructor function of the RuntimeNVParamLib.
@param ImageHandle The image handle.
@param SystemTable The system table.
@retval EFI_SUCCESS Operation succeeded.
@retval Others An error has occurred
**/
EFI_STATUS
EFIAPI
NVParamLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_EVENT VirtualAddressChangeEvent = NULL;
EFI_STATUS Status;
Status = gBS->LocateProtocol (
&gEfiMmCommunication2ProtocolGuid,
NULL,
(VOID **)&mMmCommunicationProtocol
);
ASSERT_EFI_ERROR (Status);
Status = gBS->CreateEvent (
EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
TPL_CALLBACK,
NVParamLibAddressChangeEvent,
NULL,
&VirtualAddressChangeEvent
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Provides an interface to access the NVParam services via MM interface.
@param[in] Request Pointer to the request buffer
@param[in] RequestDataSize Size of the request buffer.
@param[out] Response Pointer to the response buffer
@param[in] ResponseDataSize Size of the response buffer.
@retval EFI_SUCCESS Operation succeeded.
@retval EFI_INVALID_PARAMETER An invalid data parameter or an invalid
combination of data parameters.
@retval Others An error has occurred.
**/
EFI_STATUS
NVParamMmCommunicate (
IN VOID *Request,
IN UINT32 RequestDataSize,
OUT VOID *Response,
IN UINT32 ResponseDataSize
)
{
EFI_MM_COMMUNICATE_REQUEST CommBuffer;
EFI_STATUS Status;
if ( (Request == NULL) || (RequestDataSize == 0)
|| (RequestDataSize > EFI_MM_MAX_PAYLOAD_SIZE)
|| ((ResponseDataSize == 0) && (Response == NULL)))
{
return EFI_INVALID_PARAMETER;
}
CopyGuid (&CommBuffer.HeaderGuid, &gNVParamMmGuid);
CommBuffer.MessageLength = RequestDataSize;
CopyMem (CommBuffer.Data, Request, RequestDataSize);
if (mMmCommunicationProtocol == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = mMmCommunicationProtocol->Communicate (
mMmCommunicationProtocol,
&CommBuffer,
&CommBuffer,
NULL
);
if (EFI_ERROR (Status)) {
return Status;
}
if (ResponseDataSize > 0) {
CopyMem (Response, CommBuffer.Data, ResponseDataSize);
}
return EFI_SUCCESS;
}
|