Each one of the "PreSmmInitRegisterTable" and "RegisterTable" fields in
ACPI_CPU_DATA is a pointer to an array of CPU_REGISTER_TABLE objects; one
object per logical processor. Each table carries a variable number of
CPU_REGISTER_TABLE_ENTRY objects; each entry prescribes a specific
register setting for the CPU whose CPU_REGISTER_TABLE the entry is in.

Such entries are added to the tables with the following CpuConfigLib
functions:
- WriteRegisterTableEx(): internal helper,
- WriteRegisterTable(): public function for RegisterTable,
- WritePreSmmInitRegisterTable(): public function for
  PreSmmInitRegisterTable.

* The driver

    Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/CpuMpDxe/

  allocates the array of CPU_REGISTER_TABLEs in AcpiNVS for
  ACPI_CPU_DATA.PreSmmInitRegisterTable, and sets the InitialApicID field
  of each table object. (This is then later used by PiSmmCpuDxeSmm to
  match a table against a logical CPU.)

  However, CpuMpDxe never actually adds any register entries to any
  processor's table in the PreSmmInitRegisterTable, either with
  WritePreSmmInitRegisterTable(), or manually.

* CpuMpDxe is theoretically capable of adding register entries (MSR, CRn
  changes etc) to the elements of the array pointed-to by
  ACPI_CPU_DATA.RegisterTable. See the following call tree in CpuMpDxe:

  ProduceRegisterTable()
    MaxCpuidLimitReg()
      WriteRegisterTable(
        ..., MSR_IA32_MISC_ENABLE, N_MSR_LIMIT_CPUID_MAXVAL, ...
        )
    XdReg()
      WriteRegisterTable(
        ..., MSR_IA32_MISC_ENABLE, N_MSR_XD_BIT_DISABLE, ...
        )

  However, both MaxCpuidLimitReg() and XdReg() are gated by feature PCDs;
  we'll just consider those disabled.

Therefore, we'll explicitly instruct PiSmmCpuDxeSmm to do nothing in
response to these tables: we allocate both arrays, but leave them
zero-filled.

That will short-circuit the processing in PiSmmCpuDxeSmm for most logical
CPUs, in the

  (RegisterTableList[Index].InitialApicId == InitApicId)

checks. And when those checks don't fail, and SetProcessorRegister() gets
called, then the

  RegisterTable->TableLength == 0

equality will short-circuit that function.

Suggested-by: Michael Kinney <michael.d.kin...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
---

Notes:
    v2:
    - This patch replaces the following v1 patches:
      - OvmfPkg: QuarkPort: drop ACPI_CPU_DATA.PreSmmInitRegisterTable
      - OvmfPkg: QuarkPort: drop ACPI_CPU_DATA.RegisterTable
      It intends to have the same effect, but without modifying the
      ACPI_CPU_DATA structure, or PiSmmCpuDxeSmm.

 OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c 
b/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c
index 25ac8b1..1f4a081 100644
--- a/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c
+++ b/OvmfPkg/QuarkPort/CpuS3DataDxe/ProcessorConfig.c
@@ -57,6 +57,9 @@ PrepareMemoryForConfiguration (
   VOID
   )
 {
+  UINTN                NumberOfProcessors;
+  UINTN                RegisterTableSize;
+
   //
   // Claim memory for AP stack.
   //
@@ -64,6 +67,17 @@ PrepareMemoryForConfiguration (
                                 PcdGet32 (PcdCpuMaxLogicalProcessorNumber) *
                                 PcdGet32 (PcdCpuApStackSize)
                                 );
+
+  //
+  // OVMF port note: leaving these tables zero-filled tells PiSmmCpuDxeSmm that
+  // there is no work to do.
+  //
+  NumberOfProcessors = mCpuConfigConextBuffer.NumberOfProcessors;
+  RegisterTableSize = sizeof (CPU_REGISTER_TABLE) * NumberOfProcessors;
+  mCpuConfigConextBuffer.RegisterTable =
+    AllocateAcpiNvsMemoryBelow4G (RegisterTableSize);
+  mCpuConfigConextBuffer.PreSmmInitRegisterTable =
+    AllocateAcpiNvsMemoryBelow4G (RegisterTableSize);
 }
 
 /**
@@ -294,6 +308,12 @@ SaveCpuS3Data (
   mAcpiCpuData->StackSize      = PcdGet32 (PcdCpuApStackSize);
   mAcpiCpuData->MtrrTable      = (EFI_PHYSICAL_ADDRESS)(UINTN)MtrrSettings;
 
+  mAcpiCpuData->RegisterTable =
+    (EFI_PHYSICAL_ADDRESS)(UINTN)mCpuConfigConextBuffer.RegisterTable;
+  mAcpiCpuData->PreSmmInitRegisterTable =
+    (EFI_PHYSICAL_ADDRESS)(UINTN)
+      mCpuConfigConextBuffer.PreSmmInitRegisterTable;
+
   mAcpiCpuData->ApMachineCheckHandlerBase = mApMachineCheckHandlerBase;
   mAcpiCpuData->ApMachineCheckHandlerSize = mApMachineCheckHandlerSize;
 
-- 
1.8.3.1


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to