Home | History | Annotate | Download | only in CpuMpPei
      1 /** @file
      2   Definitions to install Multiple Processor PPI.
      3 
      4   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #ifndef _CPU_MP_PEI_H_
     16 #define _CPU_MP_PEI_H_
     17 
     18 #include <PiPei.h>
     19 
     20 #include <Ppi/MpServices.h>
     21 #include <Ppi/SecPlatformInformation.h>
     22 #include <Ppi/SecPlatformInformation2.h>
     23 #include <Ppi/EndOfPeiPhase.h>
     24 
     25 #include <Register/Cpuid.h>
     26 #include <Register/LocalApic.h>
     27 
     28 #include <Library/BaseLib.h>
     29 #include <Library/BaseMemoryLib.h>
     30 #include <Library/DebugLib.h>
     31 #include <Library/HobLib.h>
     32 #include <Library/LocalApicLib.h>
     33 #include <Library/MtrrLib.h>
     34 #include <Library/PcdLib.h>
     35 #include <Library/PeimEntryPoint.h>
     36 #include <Library/PeiServicesLib.h>
     37 #include <Library/ReportStatusCodeLib.h>
     38 #include <Library/SynchronizationLib.h>
     39 #include <Library/TimerLib.h>
     40 #include <Library/UefiCpuLib.h>
     41 #include <Library/CpuLib.h>
     42 
     43 #include "Microcode.h"
     44 
     45 //
     46 // AP state
     47 //
     48 typedef enum {
     49   CpuStateIdle,
     50   CpuStateBusy,
     51   CpuStateDisabled
     52 } CPU_STATE;
     53 
     54 #define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
     55 
     56 typedef enum {
     57   ApInHltLoop   = 1,
     58   ApInMwaitLoop = 2,
     59   ApInRunLoop   = 3
     60 } AP_LOOP_MODE;
     61 
     62 //
     63 // AP reset code information
     64 //
     65 typedef struct {
     66   UINT8             *RendezvousFunnelAddress;
     67   UINTN             PModeEntryOffset;
     68   UINTN             LModeEntryOffset;
     69   UINTN             RendezvousFunnelSize;
     70 } MP_ASSEMBLY_ADDRESS_MAP;
     71 
     72 //
     73 // CPU exchange information for switch BSP
     74 //
     75 typedef struct {
     76   UINT8             State;        // offset 0
     77   UINTN             StackPointer; // offset 4 / 8
     78   IA32_DESCRIPTOR   Gdtr;         // offset 8 / 16
     79   IA32_DESCRIPTOR   Idtr;         // offset 14 / 26
     80 } CPU_EXCHANGE_ROLE_INFO;
     81 
     82 typedef struct _PEI_CPU_MP_DATA  PEI_CPU_MP_DATA;
     83 
     84 #pragma pack(1)
     85 
     86 typedef union {
     87   struct {
     88     UINT32  LimitLow    : 16;
     89     UINT32  BaseLow     : 16;
     90     UINT32  BaseMid     : 8;
     91     UINT32  Type        : 4;
     92     UINT32  System      : 1;
     93     UINT32  Dpl         : 2;
     94     UINT32  Present     : 1;
     95     UINT32  LimitHigh   : 4;
     96     UINT32  Software    : 1;
     97     UINT32  Reserved    : 1;
     98     UINT32  DefaultSize : 1;
     99     UINT32  Granularity : 1;
    100     UINT32  BaseHigh    : 8;
    101   } Bits;
    102   UINT64  Uint64;
    103 } IA32_GDT;
    104 
    105 //
    106 // MP CPU exchange information for AP reset code
    107 // This structure is required to be packed because fixed field offsets
    108 // into this structure are used in assembly code in this module
    109 //
    110 typedef struct {
    111   UINTN                 Lock;
    112   UINTN                 StackStart;
    113   UINTN                 StackSize;
    114   UINTN                 CFunction;
    115   IA32_DESCRIPTOR       GdtrProfile;
    116   IA32_DESCRIPTOR       IdtrProfile;
    117   UINTN                 BufferStart;
    118   UINTN                 PmodeOffset;
    119   UINTN                 NumApsExecuting;
    120   UINTN                 LmodeOffset;
    121   UINTN                 Cr3;
    122   PEI_CPU_MP_DATA       *PeiCpuMpData;
    123 } MP_CPU_EXCHANGE_INFO;
    124 
    125 #pragma pack()
    126 
    127 typedef struct {
    128   UINTN                          Cr0;
    129   UINTN                          Cr3;
    130   UINTN                          Cr4;
    131   UINTN                          Dr0;
    132   UINTN                          Dr1;
    133   UINTN                          Dr2;
    134   UINTN                          Dr3;
    135   UINTN                          Dr6;
    136   UINTN                          Dr7;
    137 } CPU_VOLATILE_REGISTERS;
    138 
    139 typedef struct {
    140   volatile UINT32                *StartupApSignal;
    141   UINT32                         ApicId;
    142   EFI_HEALTH_FLAGS               Health;
    143   CPU_STATE                      State;
    144   BOOLEAN                        CpuHealthy;
    145   CPU_VOLATILE_REGISTERS         VolatileRegisters;
    146 } PEI_CPU_DATA;
    147 
    148 //
    149 // PEI CPU MP Data save in memory
    150 //
    151 struct _PEI_CPU_MP_DATA {
    152   SPIN_LOCK                      MpLock;
    153   UINT32                         CpuCount;
    154   UINT32                         BspNumber;
    155   UINTN                          Buffer;
    156   UINTN                          CpuApStackSize;
    157   MP_ASSEMBLY_ADDRESS_MAP        AddressMap;
    158   UINTN                          WakeupBuffer;
    159   UINTN                          BackupBuffer;
    160   UINTN                          BackupBufferSize;
    161   UINTN                          ApFunction;
    162   UINTN                          ApFunctionArgument;
    163   volatile UINT32                FinishedCount;
    164   BOOLEAN                        EndOfPeiFlag;
    165   BOOLEAN                        InitFlag;
    166   BOOLEAN                        X2ApicEnable;
    167   CPU_EXCHANGE_ROLE_INFO         BSPInfo;
    168   CPU_EXCHANGE_ROLE_INFO         APInfo;
    169   MTRR_SETTINGS                  MtrrTable;
    170   UINT8                          ApLoopMode;
    171   UINT8                          ApTargetCState;
    172   PEI_CPU_DATA                   *CpuData;
    173   volatile MP_CPU_EXCHANGE_INFO  *MpCpuExchangeInfo;
    174 };
    175 extern EFI_PEI_PPI_DESCRIPTOR   mPeiCpuMpPpiDesc;
    176 
    177 
    178 /**
    179   Assembly code to get starting address and size of the rendezvous entry for APs.
    180   Information for fixing a jump instruction in the code is also returned.
    181 
    182   @param AddressMap  Output buffer for address map information.
    183 **/
    184 VOID
    185 EFIAPI
    186 AsmGetAddressMap (
    187   OUT MP_ASSEMBLY_ADDRESS_MAP    *AddressMap
    188   );
    189 
    190 /**
    191   Assembly code to load GDT table and update segment accordingly.
    192 
    193   @param Gdtr   Pointer to GDT descriptor
    194 **/
    195 VOID
    196 EFIAPI
    197 AsmInitializeGdt (
    198   IN IA32_DESCRIPTOR  *Gdtr
    199   );
    200 
    201 /**
    202   Get available system memory below 1MB by specified size.
    203 
    204   @param PeiCpuMpData        Pointer to PEI CPU MP Data
    205 **/
    206 VOID
    207 BackupAndPrepareWakeupBuffer(
    208   IN PEI_CPU_MP_DATA         *PeiCpuMpData
    209   );
    210 
    211 /**
    212   Restore wakeup buffer data.
    213 
    214   @param PeiCpuMpData        Pointer to PEI CPU MP Data
    215 **/
    216 VOID
    217 RestoreWakeupBuffer(
    218   IN PEI_CPU_MP_DATA         *PeiCpuMpData
    219   );
    220 
    221 /**
    222   Notify function on End Of Pei PPI.
    223 
    224   On S3 boot, this function will restore wakeup buffer data.
    225   On normal boot, this function will flag wakeup buffer to be un-used type.
    226 
    227   @param  PeiServices        The pointer to the PEI Services Table.
    228   @param  NotifyDescriptor   Address of the notification descriptor data structure.
    229   @param  Ppi                Address of the PPI that was installed.
    230 
    231   @retval EFI_SUCCESS        When everything is OK.
    232 
    233 **/
    234 EFI_STATUS
    235 EFIAPI
    236 CpuMpEndOfPeiCallback (
    237   IN      EFI_PEI_SERVICES        **PeiServices,
    238   IN EFI_PEI_NOTIFY_DESCRIPTOR    *NotifyDescriptor,
    239   IN VOID                         *Ppi
    240   );
    241 
    242 /**
    243   This function will be called by BSP to wakeup AP.
    244 
    245   @param PeiCpuMpData       Pointer to PEI CPU MP Data
    246   @param Broadcast          TRUE:  Send broadcast IPI to all APs
    247                             FALSE: Send IPI to AP by ApicId
    248   @param ProcessorNumber    The handle number of specified processor
    249   @param Procedure          The function to be invoked by AP
    250   @param ProcedureArgument  The argument to be passed into AP function
    251 **/
    252 VOID
    253 WakeUpAP (
    254   IN PEI_CPU_MP_DATA           *PeiCpuMpData,
    255   IN BOOLEAN                   Broadcast,
    256   IN UINTN                     ProcessorNumber,
    257   IN EFI_AP_PROCEDURE          Procedure,              OPTIONAL
    258   IN VOID                      *ProcedureArgument      OPTIONAL
    259   );
    260 
    261 /**
    262   Get CPU MP Data pointer from the Guided HOB.
    263 
    264   @return  Pointer to Pointer to PEI CPU MP Data
    265 **/
    266 PEI_CPU_MP_DATA *
    267 GetMpHobData (
    268   VOID
    269   );
    270 
    271 /**
    272   Find the current Processor number by APIC ID.
    273 
    274   @param PeiCpuMpData        Pointer to PEI CPU MP Data
    275   @param ProcessorNumber     Return the pocessor number found
    276 
    277   @retval EFI_SUCCESS        ProcessorNumber is found and returned.
    278   @retval EFI_NOT_FOUND      ProcessorNumber is not found.
    279 **/
    280 EFI_STATUS
    281 GetProcessorNumber (
    282   IN PEI_CPU_MP_DATA         *PeiCpuMpData,
    283   OUT UINTN                  *ProcessorNumber
    284   );
    285 
    286 /**
    287   Collects BIST data from PPI.
    288 
    289   This function collects BIST data from Sec Platform Information2 PPI
    290   or SEC Platform Information PPI.
    291 
    292   @param PeiServices         Pointer to PEI Services Table
    293   @param PeiCpuMpData        Pointer to PEI CPU MP Data
    294 
    295 **/
    296 VOID
    297 CollectBistDataFromPpi (
    298   IN CONST EFI_PEI_SERVICES             **PeiServices,
    299   IN PEI_CPU_MP_DATA                    *PeiCpuMpData
    300   );
    301 
    302 /**
    303   Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
    304 
    305   @param  PeiServices                The pointer to the PEI Services Table.
    306   @param  StructureSize              The pointer to the variable describing size of the input buffer.
    307   @param  PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
    308 
    309   @retval EFI_SUCCESS                The data was successfully returned.
    310   @retval EFI_BUFFER_TOO_SMALL       The buffer was too small. The current buffer size needed to
    311                                      hold the record is returned in StructureSize.
    312 
    313 **/
    314 EFI_STATUS
    315 EFIAPI
    316 SecPlatformInformation2 (
    317   IN CONST EFI_PEI_SERVICES                   **PeiServices,
    318   IN OUT UINT64                               *StructureSize,
    319      OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
    320   );
    321 
    322 #endif
    323