1 /** @file
2 
3   A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the
4   EFI_SMM_CONTROL2_PROTOCOL.
5 
6   We expect the PEI phase to have covered the following:
7   - ensure that the underlying QEMU machine type be Q35
8     (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf)
9   - ensure that the ACPI PM IO space be configured
10     (responsible: OvmfPkg/PlatformPei/PlatformPei.inf)
11 
12   Our own entry point is responsible for confirming the SMI feature and for
13   configuring it.
14 
15   Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
16   Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
17 
18   SPDX-License-Identifier: BSD-2-Clause-Patent
19 
20 **/
21 
22 #include <IndustryStandard/Q35MchIch9.h>
23 #include <Library/BaseLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/IoLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/PciLib.h>
28 #include <Library/QemuFwCfgLib.h>
29 #include <Library/QemuFwCfgS3Lib.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Protocol/S3SaveState.h>
32 #include <Protocol/SmmControl2.h>
33 
34 #include "SmiFeatures.h"
35 
36 //
37 // Forward declaration.
38 //
39 STATIC
40 VOID
41 EFIAPI
42 OnS3SaveStateInstalled (
43   IN EFI_EVENT Event,
44   IN VOID      *Context
45   );
46 
47 //
48 // The absolute IO port address of the SMI Control and Enable Register. It is
49 // only used to carry information from the entry point function to the
50 // S3SaveState protocol installation callback, strictly before the runtime
51 // phase.
52 //
53 STATIC UINTN mSmiEnable;
54 
55 //
56 // Captures whether SMI feature negotiation is supported. The variable is only
57 // used to carry this information from the entry point function to the
58 // S3SaveState protocol installation callback.
59 //
60 STATIC BOOLEAN mSmiFeatureNegotiation;
61 
62 //
63 // Event signaled when an S3SaveState protocol interface is installed.
64 //
65 STATIC EFI_EVENT mS3SaveStateInstalled;
66 
67 /**
68   Invokes SMI activation from either the preboot or runtime environment.
69 
70   This function generates an SMI.
71 
72   @param[in]     This                The EFI_SMM_CONTROL2_PROTOCOL instance.
73   @param[in,out] CommandPort         The value written to the command port.
74   @param[in,out] DataPort            The value written to the data port.
75   @param[in]     Periodic            Optional mechanism to engender a periodic
76                                      stream.
77   @param[in]     ActivationInterval  Optional parameter to repeat at this
78                                      period one time or, if the Periodic
79                                      Boolean is set, periodically.
80 
81   @retval EFI_SUCCESS            The SMI/PMI has been engendered.
82   @retval EFI_DEVICE_ERROR       The timing is unsupported.
83   @retval EFI_INVALID_PARAMETER  The activation period is unsupported.
84   @retval EFI_INVALID_PARAMETER  The last periodic activation has not been
85                                  cleared.
86   @retval EFI_NOT_STARTED        The SMM base service has not been initialized.
87 **/
88 STATIC
89 EFI_STATUS
90 EFIAPI
SmmControl2DxeTrigger(IN CONST EFI_SMM_CONTROL2_PROTOCOL * This,IN OUT UINT8 * CommandPort OPTIONAL,IN OUT UINT8 * DataPort OPTIONAL,IN BOOLEAN Periodic OPTIONAL,IN UINTN ActivationInterval OPTIONAL)91 SmmControl2DxeTrigger (
92   IN CONST EFI_SMM_CONTROL2_PROTOCOL  *This,
93   IN OUT UINT8                        *CommandPort       OPTIONAL,
94   IN OUT UINT8                        *DataPort          OPTIONAL,
95   IN BOOLEAN                          Periodic           OPTIONAL,
96   IN UINTN                            ActivationInterval OPTIONAL
97   )
98 {
99   //
100   // No support for queued or periodic activation.
101   //
102   if (Periodic || ActivationInterval > 0) {
103     return EFI_DEVICE_ERROR;
104   }
105 
106   //
107   // The so-called "Advanced Power Management Status Port Register" is in fact
108   // a generic data passing register, between the caller and the SMI
109   // dispatcher. The ICH9 spec calls it "scratchpad register" --  calling it
110   // "status" elsewhere seems quite the misnomer. Status registers usually
111   // report about hardware status, while this register is fully governed by
112   // software.
113   //
114   // Write to the status register first, as this won't trigger the SMI just
115   // yet. Then write to the control register.
116   //
117   IoWrite8 (ICH9_APM_STS, DataPort    == NULL ? 0 : *DataPort);
118   IoWrite8 (ICH9_APM_CNT, CommandPort == NULL ? 0 : *CommandPort);
119   return EFI_SUCCESS;
120 }
121 
122 /**
123   Clears any system state that was created in response to the Trigger() call.
124 
125   This function acknowledges and causes the deassertion of the SMI activation
126   source.
127 
128   @param[in] This                The EFI_SMM_CONTROL2_PROTOCOL instance.
129   @param[in] Periodic            Optional parameter to repeat at this period
130                                  one time
131 
132   @retval EFI_SUCCESS            The SMI/PMI has been engendered.
133   @retval EFI_DEVICE_ERROR       The source could not be cleared.
134   @retval EFI_INVALID_PARAMETER  The service did not support the Periodic input
135                                  argument.
136 **/
137 STATIC
138 EFI_STATUS
139 EFIAPI
SmmControl2DxeClear(IN CONST EFI_SMM_CONTROL2_PROTOCOL * This,IN BOOLEAN Periodic OPTIONAL)140 SmmControl2DxeClear (
141   IN CONST EFI_SMM_CONTROL2_PROTOCOL  *This,
142   IN BOOLEAN                          Periodic OPTIONAL
143   )
144 {
145   if (Periodic) {
146     return EFI_INVALID_PARAMETER;
147   }
148 
149   //
150   // The PI spec v1.4 explains that Clear() is only supposed to clear software
151   // status; it is not in fact responsible for deasserting the SMI. It gives
152   // two reasons for this: (a) many boards clear the SMI automatically when
153   // entering SMM, (b) if Clear() actually deasserted the SMI, then it could
154   // incorrectly suppress an SMI that was asynchronously asserted between the
155   // last return of the SMI handler and the call made to Clear().
156   //
157   // In fact QEMU automatically deasserts CPU_INTERRUPT_SMI in:
158   // - x86_cpu_exec_interrupt() [target-i386/seg_helper.c], and
159   // - kvm_arch_pre_run() [target-i386/kvm.c].
160   //
161   // So, nothing to do here.
162   //
163   return EFI_SUCCESS;
164 }
165 
166 STATIC EFI_SMM_CONTROL2_PROTOCOL mControl2 = {
167   &SmmControl2DxeTrigger,
168   &SmmControl2DxeClear,
169   MAX_UINTN // MinimumTriggerPeriod -- we don't support periodic SMIs
170 };
171 
172 //
173 // Entry point of this driver.
174 //
175 EFI_STATUS
176 EFIAPI
SmmControl2DxeEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)177 SmmControl2DxeEntryPoint (
178   IN EFI_HANDLE       ImageHandle,
179   IN EFI_SYSTEM_TABLE *SystemTable
180   )
181 {
182   UINT32     PmBase;
183   UINT32     SmiEnableVal;
184   EFI_STATUS Status;
185 
186   //
187   // This module should only be included if SMRAM support is required.
188   //
189   ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
190 
191   //
192   // Calculate the absolute IO port address of the SMI Control and Enable
193   // Register. (As noted at the top, the PEI phase has left us with a working
194   // ACPI PM IO space.)
195   //
196   PmBase = PciRead32 (POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE)) &
197     ICH9_PMBASE_MASK;
198   mSmiEnable = PmBase + ICH9_PMBASE_OFS_SMI_EN;
199 
200   //
201   // If APMC_EN is pre-set in SMI_EN, that's QEMU's way to tell us that SMI
202   // support is not available. (For example due to KVM lacking it.) Otherwise,
203   // this bit is clear after each reset.
204   //
205   SmiEnableVal = IoRead32 (mSmiEnable);
206   if ((SmiEnableVal & ICH9_SMI_EN_APMC_EN) != 0) {
207     DEBUG ((DEBUG_ERROR, "%a: this Q35 implementation lacks SMI\n",
208       __FUNCTION__));
209     goto FatalError;
210   }
211 
212   //
213   // Otherwise, configure the board to inject an SMI when ICH9_APM_CNT is
214   // written to. (See the Trigger() method above.)
215   //
216   SmiEnableVal |= ICH9_SMI_EN_APMC_EN | ICH9_SMI_EN_GBL_SMI_EN;
217   IoWrite32 (mSmiEnable, SmiEnableVal);
218 
219   //
220   // Prevent software from undoing the above (until platform reset).
221   //
222   PciOr16 (POWER_MGMT_REGISTER_Q35 (ICH9_GEN_PMCON_1),
223     ICH9_GEN_PMCON_1_SMI_LOCK);
224 
225   //
226   // If we can clear GBL_SMI_EN now, that means QEMU's SMI support is not
227   // appropriate.
228   //
229   IoWrite32 (mSmiEnable, SmiEnableVal & ~(UINT32)ICH9_SMI_EN_GBL_SMI_EN);
230   if (IoRead32 (mSmiEnable) != SmiEnableVal) {
231     DEBUG ((DEBUG_ERROR, "%a: failed to lock down GBL_SMI_EN\n",
232       __FUNCTION__));
233     goto FatalError;
234   }
235 
236   //
237   // QEMU can inject SMIs in different ways, negotiate our preferences.
238   //
239   mSmiFeatureNegotiation = NegotiateSmiFeatures ();
240 
241   if (QemuFwCfgS3Enabled ()) {
242     VOID *Registration;
243 
244     //
245     // On S3 resume the above register settings have to be repeated. Register a
246     // protocol notify callback that, when boot script saving becomes
247     // available, saves operations equivalent to the above to the boot script.
248     //
249     Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
250                     OnS3SaveStateInstalled, NULL /* Context */,
251                     &mS3SaveStateInstalled);
252     if (EFI_ERROR (Status)) {
253       DEBUG ((DEBUG_ERROR, "%a: CreateEvent: %r\n", __FUNCTION__, Status));
254       goto FatalError;
255     }
256 
257     Status = gBS->RegisterProtocolNotify (&gEfiS3SaveStateProtocolGuid,
258                     mS3SaveStateInstalled, &Registration);
259     if (EFI_ERROR (Status)) {
260       DEBUG ((DEBUG_ERROR, "%a: RegisterProtocolNotify: %r\n", __FUNCTION__,
261         Status));
262       goto ReleaseEvent;
263     }
264 
265     //
266     // Kick the event right now -- maybe the boot script is already saveable.
267     //
268     Status = gBS->SignalEvent (mS3SaveStateInstalled);
269     if (EFI_ERROR (Status)) {
270       DEBUG ((DEBUG_ERROR, "%a: SignalEvent: %r\n", __FUNCTION__, Status));
271       goto ReleaseEvent;
272     }
273   }
274 
275   //
276   // We have no pointers to convert to virtual addresses. The handle itself
277   // doesn't matter, as protocol services are not accessible at runtime.
278   //
279   Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
280                   &gEfiSmmControl2ProtocolGuid, &mControl2,
281                   NULL);
282   if (EFI_ERROR (Status)) {
283     DEBUG ((DEBUG_ERROR, "%a: InstallMultipleProtocolInterfaces: %r\n",
284       __FUNCTION__, Status));
285     goto ReleaseEvent;
286   }
287 
288   return EFI_SUCCESS;
289 
290 ReleaseEvent:
291   if (mS3SaveStateInstalled != NULL) {
292     gBS->CloseEvent (mS3SaveStateInstalled);
293   }
294 
295 FatalError:
296   //
297   // We really don't want to continue in this case.
298   //
299   ASSERT (FALSE);
300   CpuDeadLoop ();
301   return EFI_UNSUPPORTED;
302 }
303 
304 /**
305   Notification callback for S3SaveState installation.
306 
307   @param[in] Event    Event whose notification function is being invoked.
308 
309   @param[in] Context  The pointer to the notification function's context, which
310                       is implementation-dependent.
311 **/
312 STATIC
313 VOID
314 EFIAPI
OnS3SaveStateInstalled(IN EFI_EVENT Event,IN VOID * Context)315 OnS3SaveStateInstalled (
316   IN EFI_EVENT Event,
317   IN VOID      *Context
318   )
319 {
320   EFI_STATUS                 Status;
321   EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState;
322   UINT32                     SmiEnOrMask, SmiEnAndMask;
323   UINT64                     GenPmCon1Address;
324   UINT16                     GenPmCon1OrMask, GenPmCon1AndMask;
325 
326   ASSERT (Event == mS3SaveStateInstalled);
327 
328   Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid,
329                   NULL /* Registration */, (VOID **)&S3SaveState);
330   if (EFI_ERROR (Status)) {
331     return;
332   }
333 
334   //
335   // These operations were originally done, verified and explained in the entry
336   // point function of the driver.
337   //
338   SmiEnOrMask  = ICH9_SMI_EN_APMC_EN | ICH9_SMI_EN_GBL_SMI_EN;
339   SmiEnAndMask = MAX_UINT32;
340   Status = S3SaveState->Write (
341                           S3SaveState,
342                           EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE,
343                           EfiBootScriptWidthUint32,
344                           (UINT64)mSmiEnable,
345                           &SmiEnOrMask,
346                           &SmiEnAndMask
347                           );
348   if (EFI_ERROR (Status)) {
349     DEBUG ((DEBUG_ERROR, "%a: EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: %r\n",
350       __FUNCTION__, Status));
351     ASSERT (FALSE);
352     CpuDeadLoop ();
353   }
354 
355   GenPmCon1Address = POWER_MGMT_REGISTER_Q35_EFI_PCI_ADDRESS (
356                        ICH9_GEN_PMCON_1);
357   GenPmCon1OrMask  = ICH9_GEN_PMCON_1_SMI_LOCK;
358   GenPmCon1AndMask = MAX_UINT16;
359   Status = S3SaveState->Write (
360                           S3SaveState,
361                           EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE,
362                           EfiBootScriptWidthUint16,
363                           GenPmCon1Address,
364                           &GenPmCon1OrMask,
365                           &GenPmCon1AndMask
366                           );
367   if (EFI_ERROR (Status)) {
368     DEBUG ((DEBUG_ERROR,
369       "%a: EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: %r\n", __FUNCTION__,
370       Status));
371     ASSERT (FALSE);
372     CpuDeadLoop ();
373   }
374 
375   DEBUG ((DEBUG_VERBOSE, "%a: chipset boot script saved\n", __FUNCTION__));
376 
377   //
378   // Append a boot script fragment that re-selects the negotiated SMI features.
379   //
380   if (mSmiFeatureNegotiation) {
381     SaveSmiFeatures ();
382   }
383 
384   gBS->CloseEvent (Event);
385   mS3SaveStateInstalled = NULL;
386 }
387