Home | History | Annotate | Download | only in SmmControlPei
      1 /** @file
      2 This module provides an implementation of the SMM Control PPI for use with
      3 the QNC.
      4 
      5 Copyright (c) 2013-2015 Intel Corporation.
      6 
      7 This program and the accompanying materials
      8 are licensed and made available under the terms and conditions of the BSD License
      9 which accompanies this distribution.  The full text of the license may be found at
     10 http://opensource.org/licenses/bsd-license.php
     11 
     12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #include <PiPei.h>
     18 
     19 #include <Ppi/SmmControl.h>
     20 
     21 #include <Library/DebugLib.h>
     22 #include <Library/HobLib.h>
     23 #include <Library/PeiServicesLib.h>
     24 #include <Library/PcdLib.h>
     25 #include <Library/IoLib.h>
     26 #include <Library/PciLib.h>
     27 
     28 #include <IntelQNCPeim.h>
     29 #include <Library/QNCAccessLib.h>
     30 #include <Uefi/UefiBaseType.h>
     31 
     32 /**
     33   Generates an SMI using the parameters passed in.
     34 
     35   @param  PeiServices         Describes the list of possible PEI Services.
     36   @param  This                A pointer to an instance of
     37                               EFI_SMM_CONTROL_PPI
     38   @param  ArgumentBuffer      The argument buffer
     39   @param  ArgumentBufferSize  The size of the argument buffer
     40   @param  Periodic            TRUE to indicate a periodical SMI
     41   @param  ActivationInterval  Interval of the periodical SMI
     42 
     43   @retval EFI_INVALID_PARAMETER  Periodic is TRUE or ArgumentBufferSize > 1
     44   @retval EFI_SUCCESS            SMI generated
     45 
     46 **/
     47 EFI_STATUS
     48 EFIAPI
     49 PeiActivate (
     50   IN      EFI_PEI_SERVICES           **PeiServices,
     51   IN      PEI_SMM_CONTROL_PPI        *This,
     52   IN OUT  INT8                       *ArgumentBuffer OPTIONAL,
     53   IN OUT  UINTN                      *ArgumentBufferSize OPTIONAL,
     54   IN      BOOLEAN                    Periodic OPTIONAL,
     55   IN      UINTN                      ActivationInterval OPTIONAL
     56   );
     57 
     58 /**
     59   Clears an SMI.
     60 
     61   @param  PeiServices         Describes the list of possible PEI Services.
     62   @param  This                Pointer to an instance of EFI_SMM_CONTROL_PPI
     63   @param  Periodic            TRUE to indicate a periodical SMI
     64 
     65   @return Return value from SmmClear()
     66 
     67 **/
     68 EFI_STATUS
     69 EFIAPI
     70 PeiDeactivate (
     71   IN  EFI_PEI_SERVICES            **PeiServices,
     72   IN  PEI_SMM_CONTROL_PPI         *This,
     73   IN  BOOLEAN                     Periodic OPTIONAL
     74   );
     75 
     76 PEI_SMM_CONTROL_PPI      mSmmControlPpi = {
     77   PeiActivate,
     78   PeiDeactivate
     79 };
     80 
     81 EFI_PEI_PPI_DESCRIPTOR   mPpiList = {
     82   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     83   &gPeiSmmControlPpiGuid,
     84   &mSmmControlPpi
     85 };
     86 
     87 /**
     88   Clear SMI related chipset status and re-enable SMI by setting the EOS bit.
     89 
     90   @retval EFI_SUCCESS       The requested operation has been carried out successfully
     91   @retval EFI_DEVICE_ERROR  The EOS bit could not be set.
     92 
     93 **/
     94 EFI_STATUS
     95 SmmClear (
     96   VOID
     97   )
     98 {
     99   UINT16                       GPE0BLK_Base;
    100 
    101   //
    102   // Get GPE0BLK_Base
    103   //
    104   GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
    105 
    106   //
    107   // Clear the Power Button Override Status Bit, it gates EOS from being set.
    108   // In QuarkNcSocId - Bit is read only. Handled by external SMC, do nothing.
    109   //
    110 
    111   //
    112   // Clear the APM SMI Status Bit
    113   //
    114   IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_APM);
    115 
    116   //
    117   // Set the EOS Bit
    118   //
    119   IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);
    120 
    121   return EFI_SUCCESS;
    122 }
    123 
    124 
    125 EFI_STATUS
    126 EFIAPI
    127 SmmTrigger (
    128   IN UINT8   Data
    129   )
    130 /*++
    131 
    132 Routine Description:
    133 
    134   Trigger the software SMI
    135 
    136 Arguments:
    137 
    138   Data                          The value to be set on the software SMI data port
    139 
    140 Returns:
    141 
    142   EFI_SUCCESS                   Function completes successfully
    143 
    144 --*/
    145 {
    146   UINT16        GPE0BLK_Base;
    147   UINT32        NewValue;
    148 
    149   //
    150   // Get GPE0BLK_Base
    151   //
    152   GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
    153 
    154   //
    155   // Enable the APMC SMI
    156   //
    157   IoOr32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIE, B_QNC_GPE0BLK_SMIE_APM);
    158 
    159   //
    160   // Enable SMI globally
    161   //
    162   NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
    163   NewValue |= SMI_EN;
    164   QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
    165 
    166 
    167   //
    168   // Generate the APMC SMI
    169   //
    170   IoWrite8 (PcdGet16 (PcdSmmActivationPort), Data);
    171 
    172   return EFI_SUCCESS;
    173 }
    174 
    175 /**
    176   Generates an SMI using the parameters passed in.
    177 
    178   @param  PeiServices         Describes the list of possible PEI Services.
    179   @param  This                A pointer to an instance of
    180                               EFI_SMM_CONTROL_PPI
    181   @param  ArgumentBuffer      The argument buffer
    182   @param  ArgumentBufferSize  The size of the argument buffer
    183   @param  Periodic            TRUE to indicate a periodical SMI
    184   @param  ActivationInterval  Interval of the periodical SMI
    185 
    186   @retval EFI_INVALID_PARAMETER  Periodic is TRUE or ArgumentBufferSize > 1
    187   @retval EFI_SUCCESS            SMI generated
    188 
    189 **/
    190 EFI_STATUS
    191 EFIAPI
    192 PeiActivate (
    193   IN      EFI_PEI_SERVICES           **PeiServices,
    194   IN      PEI_SMM_CONTROL_PPI        *This,
    195   IN OUT  INT8                       *ArgumentBuffer OPTIONAL,
    196   IN OUT  UINTN                      *ArgumentBufferSize OPTIONAL,
    197   IN      BOOLEAN                    Periodic OPTIONAL,
    198   IN      UINTN                      ActivationInterval OPTIONAL
    199   )
    200 {
    201   INT8       Data;
    202   EFI_STATUS Status;
    203   //
    204   // Periodic SMI not supported.
    205   //
    206   if (Periodic) {
    207     DEBUG ((DEBUG_WARN, "Invalid parameter\n"));
    208     return EFI_INVALID_PARAMETER;
    209   }
    210 
    211   if (ArgumentBuffer == NULL) {
    212     Data = 0xFF;
    213   } else {
    214     if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) {
    215       return EFI_INVALID_PARAMETER;
    216     }
    217 
    218     Data = *ArgumentBuffer;
    219   }
    220   //
    221   // Clear any pending the APM SMI
    222   //
    223   Status = SmmClear ();
    224   if (EFI_ERROR (Status)) {
    225     return Status;
    226   }
    227 
    228   return SmmTrigger (Data);
    229 }
    230 
    231 /**
    232   Clears an SMI.
    233 
    234   @param  PeiServices         Describes the list of possible PEI Services.
    235   @param  This                Pointer to an instance of EFI_SMM_CONTROL_PPI
    236   @param  Periodic            TRUE to indicate a periodical SMI
    237 
    238   @return Return value from SmmClear()
    239 
    240 **/
    241 EFI_STATUS
    242 EFIAPI
    243 PeiDeactivate (
    244   IN  EFI_PEI_SERVICES            **PeiServices,
    245   IN  PEI_SMM_CONTROL_PPI         *This,
    246   IN  BOOLEAN                     Periodic OPTIONAL
    247   )
    248 {
    249   if (Periodic) {
    250     return EFI_INVALID_PARAMETER;
    251   }
    252   return SmmClear ();
    253 }
    254 
    255 /**
    256   This is the constructor for the SMM Control Ppi.
    257 
    258   This function installs EFI_SMM_CONTROL_PPI.
    259 
    260   @param   FileHandle       Handle of the file being invoked.
    261   @param   PeiServices      Describes the list of possible PEI Services.
    262 
    263   @retval EFI_UNSUPPORTED There's no Intel ICH on this platform
    264   @return The status returned from InstallPpi().
    265 
    266 --*/
    267 EFI_STATUS
    268 EFIAPI
    269 SmmControlPeiEntry (
    270   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    271   IN CONST EFI_PEI_SERVICES     **PeiServices
    272   )
    273 {
    274   EFI_STATUS  Status;
    275 
    276   Status      = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
    277   ASSERT_EFI_ERROR (Status);
    278 
    279   return Status;
    280 }
    281