/** @file
Definitions for CPU S3 data.

Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef _ACPI_CPU_DATA_H_
#define _ACPI_CPU_DATA_H_

//
// This macro definition is used to fix incompatibility issue caused by
// ACPI_CPU_DATA structure update. It will be removed after all the platform
// code uses new ACPI_CPU_DATA structure.
//
#define ACPI_CPU_DATA_STRUCTURE_UPDATE

//
// Register types in register table
//
typedef enum {
  Msr,
  ControlRegister,
  MemoryMapped,
  CacheControl,

  //
  // Semaphore type used to control the execute sequence of the Msr.
  // It will be insert between two Msr which has execute dependence.
  //
  Semaphore,
  InvalidReg
} REGISTER_TYPE;

//
// Describe the dependency type for different features.
// The value set to CPU_REGISTER_TABLE_ENTRY.Value when the REGISTER_TYPE is Semaphore.
//
typedef enum {
  NoneDepType,
  ThreadDepType,
  CoreDepType,
  PackageDepType,
  InvalidDepType
} CPU_FEATURE_DEPENDENCE_TYPE;

//
// CPU information.
//
typedef struct {
  //
  // Record the package count in this CPU.
  //
  UINT32    PackageCount;
  //
  // Record the max core count in this CPU.
  // Different packages may have different core count, this value
  // save the max core count in all the packages.
  //
  UINT32    MaxCoreCount;
  //
  // Record the max thread count in this CPU.
  // Different cores may have different thread count, this value
  // save the max thread count in all the cores.
  //
  UINT32    MaxThreadCount;
  //
  // This field points to an array.
  // This array saves thread count (type UINT32) of each package.
  // The array has PackageCount elements.
  //
  // If the platform does not support MSR setting at S3 resume, and
  // therefore it doesn't need the dependency semaphores, it should set
  // this field to 0.
  //
  EFI_PHYSICAL_ADDRESS    ThreadCountPerPackage;
  //
  // This field points to an array.
  // This array saves thread count (type UINT8) of each core.
  // The array has PackageCount * MaxCoreCount elements.
  //
  // If the platform does not support MSR setting at S3 resume, and
  // therefore it doesn't need the dependency semaphores, it should set
  // this field to 0.
  //
  EFI_PHYSICAL_ADDRESS    ThreadCountPerCore;
} CPU_STATUS_INFORMATION;

//
// Element of register table entry
//
typedef struct {
  REGISTER_TYPE    RegisterType;        // offset 0 - 3
  UINT32           Index;               // offset 4 - 7
  UINT8            ValidBitStart;       // offset 8
  UINT8            ValidBitLength;      // offset 9
  BOOLEAN          TestThenWrite;       // offset 10
  UINT8            Reserved1;           // offset 11
  UINT32           HighIndex;           // offset 12-15, only valid for MemoryMapped
  UINT64           Value;               // offset 16-23
} CPU_REGISTER_TABLE_ENTRY;

//
// Register table definition, including current table length,
// allocated size of this table, and pointer to the list of table entries.
//
typedef struct {
  //
  // The number of valid entries in the RegisterTableEntry buffer
  //
  UINT32                  TableLength;
  UINT32                  NumberBeforeReset;
  //
  // The size, in bytes, of the RegisterTableEntry buffer
  //
  UINT32                  AllocatedSize;
  //
  // The initial APIC ID of the CPU this register table applies to
  //
  UINT32                  InitialApicId;
  //
  // Physical address of CPU_REGISTER_TABLE_ENTRY structures.
  //
  EFI_PHYSICAL_ADDRESS    RegisterTableEntry;
} CPU_REGISTER_TABLE;

//
// Data structure that is used for CPU feature initialization during ACPI S3
// resume.
//
typedef struct {
  //
  // Physical address of an array of CPU_REGISTER_TABLE structures, with
  // NumberOfCpus entries.  If a register table is not required, then the
  // TableLength and AllocatedSize fields of CPU_REGISTER_TABLE are set to 0.
  // If TableLength is > 0, then elements of RegisterTableEntry are used to
  // initialize the CPU that matches InitialApicId, during an ACPI S3 resume,
  // before SMBASE relocation is performed.
  // If a register table is not required for any one of the CPUs, then
  // PreSmmInitRegisterTable may be set to 0.
  //
  EFI_PHYSICAL_ADDRESS    PreSmmInitRegisterTable;
  //
  // Physical address of an array of CPU_REGISTER_TABLE structures, with
  // NumberOfCpus entries.  If a register table is not required, then the
  // TableLength and AllocatedSize fields of CPU_REGISTER_TABLE are set to 0.
  // If TableLength is > 0, then elements of RegisterTableEntry are used to
  // initialize the CPU that matches InitialApicId, during an ACPI S3 resume,
  // after SMBASE relocation is performed.
  // If a register table is not required for any one of the CPUs, then
  // RegisterTable may be set to 0.
  //
  EFI_PHYSICAL_ADDRESS      RegisterTable;
  //
  // CPU information which is required when set the register table.
  //
  CPU_STATUS_INFORMATION    CpuStatus;
  //
  // Location info for each AP.
  // It points to an array which saves all APs location info.
  // The array count is the AP count in this CPU.
  //
  // If the platform does not support MSR setting at S3 resume, and
  // therefore it doesn't need the dependency semaphores, it should set
  // this field to 0.
  //
  EFI_PHYSICAL_ADDRESS    ApLocation;
} CPU_FEATURE_INIT_DATA;

//
// Data structure that is required for ACPI S3 resume. The PCD
// PcdCpuS3DataAddress must be set to the physical address where this structure
// is allocated
//
typedef struct {
  //
  // Physical address of 4KB buffer allocated below 1MB from memory of type
  // EfiReservedMemoryType.  The buffer is not required to be initialized, but
  // it is recommended that the buffer be zero-filled.  This buffer is used to
  // wake APs during an ACPI S3 resume.
  //
  EFI_PHYSICAL_ADDRESS     StartupVector;
  //
  // Physical address of structure of type IA32_DESCRIPTOR. The
  // IA32_DESCRIPTOR structure provides the base address and length of a GDT
  // The GDT must be filled in with the GDT contents that are
  // used during an ACPI S3 resume.  This is typically the contents of the GDT
  // used by the boot processor when the platform is booted.
  //
  EFI_PHYSICAL_ADDRESS     GdtrProfile;
  //
  // Physical address of structure of type IA32_DESCRIPTOR.  The
  // IA32_DESCRIPTOR structure provides the base address and length of an IDT.
  // The IDT must be filled in with the IDT contents that are
  // used during an ACPI S3 resume.  This is typically the contents of the IDT
  // used by the boot processor when the platform is booted.
  //
  EFI_PHYSICAL_ADDRESS     IdtrProfile;
  //
  // Physical address of a buffer that is used as stacks during ACPI S3 resume.
  // The total size of this buffer, in bytes, is NumberOfCpus * StackSize.  This
  // structure must be allocated from memory of type EfiACPIMemoryNVS.
  //
  EFI_PHYSICAL_ADDRESS     StackAddress;
  //
  // The size, in bytes, of the stack provided to each CPU during ACPI S3 resume.
  //
  UINT32                   StackSize;
  //
  // The number of CPUs.  If a platform does not support hot plug CPUs, then
  // this is the number of CPUs detected when the platform is booted, regardless
  // of being enabled or disabled.  If a platform does support hot plug CPUs,
  // then this is the maximum number of CPUs that the platform supports.
  //
  UINT32                   NumberOfCpus;
  //
  // Physical address of structure of type MTRR_SETTINGS that contains a copy
  // of the MTRR settings that are compatible with the MTRR settings used by
  // the boot processor when the platform was booted.  These MTRR settings are
  // used during an ACPI S3 resume.
  //
  EFI_PHYSICAL_ADDRESS     MtrrTable;
  //
  // Physical address of a buffer that contains the machine check handler that
  // is used during an ACPI S3 Resume.  In order for this machine check
  // handler to be active on an AP during an ACPI S3 resume, the machine check
  // vector in the IDT provided by IdtrProfile must be initialized to transfer
  // control to this physical address.
  //
  EFI_PHYSICAL_ADDRESS     ApMachineCheckHandlerBase;
  //
  // The size, in bytes, of the machine check handler that is used during an
  // ACPI S3 Resume.  If this field is 0, then a machine check handler is not
  // provided.
  //
  UINT32                   ApMachineCheckHandlerSize;
  //
  // Data structure that is used for CPU feature initialization during ACPI S3
  // resume.
  //
  CPU_FEATURE_INIT_DATA    CpuFeatureInitData;
} ACPI_CPU_DATA;

#endif
