TianoCore EDK2 master
Loading...
Searching...
No Matches
SmmControlRuntimeDxe.c
Go to the documentation of this file.
1
9#include <PiDxe.h>
11#include <Library/DebugLib.h>
13#include <Library/IoLib.h>
14#include <Library/HobLib.h>
18
19#define SMM_DATA_PORT 0xB3
20#define SMM_CONTROL_PORT 0xB2
21
22typedef struct {
23 UINT8 GblBitOffset;
24 UINT8 ApmBitOffset;
25 UINT32 Address;
27
28SMM_CONTROL2_REG mSmiCtrlReg;
29
49EFIAPI
52 IN OUT UINT8 *CommandPort OPTIONAL,
53 IN OUT UINT8 *DataPort OPTIONAL,
54 IN BOOLEAN Periodic OPTIONAL,
55 IN EFI_SMM_PERIOD ActivationInterval OPTIONAL
56 )
57{
58 UINT32 SmiEn;
59 UINT32 SmiEnableBits;
60
61 if (Periodic) {
62 return EFI_INVALID_PARAMETER;
63 }
64
65 SmiEn = IoRead32 (mSmiCtrlReg.Address);
66 SmiEnableBits = (1 << mSmiCtrlReg.GblBitOffset) | (1 << mSmiCtrlReg.ApmBitOffset);
67 if ((SmiEn & SmiEnableBits) != SmiEnableBits) {
68 //
69 // Set the "global SMI enable" bit and APM bit
70 //
71 IoWrite32 (mSmiCtrlReg.Address, SmiEn | SmiEnableBits);
72 }
73
74 IoWrite8 (SMM_DATA_PORT, DataPort == NULL ? 0 : *DataPort);
75 IoWrite8 (SMM_CONTROL_PORT, CommandPort == NULL ? 0 : *CommandPort);
76 return EFI_SUCCESS;
77}
78
89EFIAPI
92 IN BOOLEAN Periodic
93 )
94{
95 if (Periodic) {
96 return EFI_INVALID_PARAMETER;
97 }
98
99 //
100 // Temporarily do nothing here
101 //
102 return EFI_SUCCESS;
103}
104
109 Activate,
111 0
112};
113
126 IN PLD_SMM_REGISTERS *SmmRegister,
127 IN UINT32 Id
128 )
129{
130 UINT32 Index;
131 PLD_GENERIC_REGISTER *PldReg;
132
133 PldReg = NULL;
134 for (Index = 0; Index < SmmRegister->Count; Index++) {
135 if (SmmRegister->Registers[Index].Id == Id) {
136 PldReg = &SmmRegister->Registers[Index];
137 break;
138 }
139 }
140
141 if (PldReg == NULL) {
142 DEBUG ((DEBUG_INFO, "Register %d not found.\n", Id));
143 return NULL;
144 }
145
146 //
147 // Checking the register if it is expected.
148 //
149 if ((PldReg->Address.AccessSize != EFI_ACPI_3_0_DWORD) ||
150 (PldReg->Address.Address == 0) ||
151 (PldReg->Address.RegisterBitWidth != 1) ||
152 (PldReg->Address.AddressSpaceId != EFI_ACPI_3_0_SYSTEM_IO) ||
153 (PldReg->Value != 1))
154 {
155 DEBUG ((DEBUG_INFO, "Unexpected SMM register.\n"));
156 DEBUG ((DEBUG_INFO, "AddressSpaceId= 0x%x\n", PldReg->Address.AddressSpaceId));
157 DEBUG ((DEBUG_INFO, "RegBitWidth = 0x%x\n", PldReg->Address.RegisterBitWidth));
158 DEBUG ((DEBUG_INFO, "RegBitOffset = 0x%x\n", PldReg->Address.RegisterBitOffset));
159 DEBUG ((DEBUG_INFO, "AccessSize = 0x%x\n", PldReg->Address.AccessSize));
160 DEBUG ((DEBUG_INFO, "Address = 0x%lx\n", PldReg->Address.Address));
161 return NULL;
162 }
163
164 return PldReg;
165}
166
174VOID
175EFIAPI
177 IN EFI_EVENT Event,
178 IN VOID *Context
179 )
180{
181 EfiConvertPointer (0x0, (VOID **)&(mSmmControl2.Trigger));
182 EfiConvertPointer (0x0, (VOID **)&(mSmmControl2.Clear));
183}
184
196EFIAPI
198 IN EFI_HANDLE ImageHandle,
199 IN EFI_SYSTEM_TABLE *SystemTable
200 )
201{
202 EFI_STATUS Status;
203 EFI_HOB_GUID_TYPE *GuidHob;
204 PLD_SMM_REGISTERS *SmmRegister;
205 PLD_GENERIC_REGISTER *SmiGblEnReg;
206 PLD_GENERIC_REGISTER *SmiApmEnReg;
207 EFI_EVENT Event;
208
210 if (GuidHob == NULL) {
211 return EFI_UNSUPPORTED;
212 }
213
214 SmmRegister = (PLD_SMM_REGISTERS *)(GET_GUID_HOB_DATA (GuidHob));
215 SmiGblEnReg = GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_GBL_EN);
216 if (SmiGblEnReg == NULL) {
217 DEBUG ((DEBUG_ERROR, "SMI global enable reg not found.\n"));
218 return EFI_NOT_FOUND;
219 }
220
221 mSmiCtrlReg.Address = (UINT32)SmiGblEnReg->Address.Address;
222 mSmiCtrlReg.GblBitOffset = SmiGblEnReg->Address.RegisterBitOffset;
223
224 SmiApmEnReg = GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_APM_EN);
225 if (SmiApmEnReg == NULL) {
226 DEBUG ((DEBUG_ERROR, "SMI APM enable reg not found.\n"));
227 return EFI_NOT_FOUND;
228 }
229
230 if (SmiApmEnReg->Address.Address != mSmiCtrlReg.Address) {
231 DEBUG ((DEBUG_ERROR, "SMI APM EN and SMI GBL EN are expected to have same register base\n"));
232 DEBUG ((DEBUG_ERROR, "APM:0x%x, GBL:0x%x\n", SmiApmEnReg->Address.Address, mSmiCtrlReg.Address));
233 return EFI_UNSUPPORTED;
234 }
235
236 mSmiCtrlReg.ApmBitOffset = SmiApmEnReg->Address.RegisterBitOffset;
237
238 //
239 // Install our protocol interfaces on the device's handle
240 //
241 Status = gBS->InstallMultipleProtocolInterfaces (
242 &ImageHandle,
243 &gEfiSmmControl2ProtocolGuid,
245 NULL
246 );
247 ASSERT_EFI_ERROR (Status);
248
249 Status = gBS->CreateEventEx (
250 EVT_NOTIFY_SIGNAL,
251 TPL_NOTIFY,
253 NULL,
254 &gEfiEventVirtualAddressChangeGuid,
255 &Event
256 );
257 return Status;
258}
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
UINT8 EFIAPI IoWrite8(IN UINTN Port, IN UINT8 Value)
Definition: IoLibArmVirt.c:200
UINT32 EFIAPI IoRead32(IN UINTN Port)
Definition: IoLibArmVirt.c:275
UINT32 EFIAPI IoWrite32(IN UINTN Port, IN UINT32 Value)
Definition: IoLibArmVirt.c:300
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
PLD_GENERIC_REGISTER * GetSmmCtrlRegById(IN PLD_SMM_REGISTERS *SmmRegister, IN UINT32 Id)
EFI_STATUS EFIAPI SmmControlEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_SMM_CONTROL2_PROTOCOL mSmmControl2
EFI_STATUS EFIAPI Activate(IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, IN OUT UINT8 *CommandPort OPTIONAL, IN OUT UINT8 *DataPort OPTIONAL, IN BOOLEAN Periodic OPTIONAL, IN EFI_SMM_PERIOD ActivationInterval OPTIONAL)
VOID EFIAPI SmmControlVirtualAddressChangeEvent(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI Deactivate(IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, IN BOOLEAN Periodic)
EFI_GUID gSmmRegisterInfoGuid
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiConvertPointer(IN UINTN DebugDisposition, IN OUT VOID **Address)
Definition: RuntimeLib.c:561