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                       PM1BLK_Base;
    100   UINT16                       GPE0BLK_Base;
    101 
    102   //
    103   // Get PM1BLK_Base & GPE0BLK_Base
    104   //
    105   PM1BLK_Base  = PcdGet16 (PcdPm1blkIoBaseAddress);
    106   GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
    107 
    108   //
    109   // Clear the Power Button Override Status Bit, it gates EOS from being set.
    110   // In QuarkNcSocId - Bit is read only. Handled by external SMC, do nothing.
    111   //
    112 
    113   //
    114   // Clear the APM SMI Status Bit
    115   //
    116   IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_APM);
    117 
    118   //
    119   // Set the EOS Bit
    120   //
    121   IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);
    122 
    123   return EFI_SUCCESS;
    124 }
    125 
    126 
    127 EFI_STATUS
    128 EFIAPI
    129 SmmTrigger (
    130   IN UINT8   Data
    131   )
    132 /*++
    133 
    134 Routine Description:
    135 
    136   Trigger the software SMI
    137 
    138 Arguments:
    139 
    140   Data                          The value to be set on the software SMI data port
    141 
    142 Returns:
    143 
    144   EFI_SUCCESS                   Function completes successfully
    145 
    146 --*/
    147 {
    148   UINT16        GPE0BLK_Base;
    149   UINT32        NewValue;
    150 
    151   //
    152   // Get GPE0BLK_Base
    153   //
    154   GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
    155 
    156   //
    157   // Enable the APMC SMI
    158   //
    159   IoOr32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIE, B_QNC_GPE0BLK_SMIE_APM);
    160 
    161   //
    162   // Enable SMI globally
    163   //
    164   NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
    165   NewValue |= SMI_EN;
    166   QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
    167 
    168 
    169   //
    170   // Generate the APMC SMI
    171   //
    172   IoWrite8 (PcdGet16 (PcdSmmActivationPort), Data);
    173 
    174   return EFI_SUCCESS;
    175 }
    176 
    177 /**
    178   Generates an SMI using the parameters passed in.
    179 
    180   @param  PeiServices         Describes the list of possible PEI Services.
    181   @param  This                A pointer to an instance of
    182                               EFI_SMM_CONTROL_PPI
    183   @param  ArgumentBuffer      The argument buffer
    184   @param  ArgumentBufferSize  The size of the argument buffer
    185   @param  Periodic            TRUE to indicate a periodical SMI
    186   @param  ActivationInterval  Interval of the periodical SMI
    187 
    188   @retval EFI_INVALID_PARAMETER  Periodic is TRUE or ArgumentBufferSize > 1
    189   @retval EFI_SUCCESS            SMI generated
    190 
    191 **/
    192 EFI_STATUS
    193 EFIAPI
    194 PeiActivate (
    195   IN      EFI_PEI_SERVICES           **PeiServices,
    196   IN      PEI_SMM_CONTROL_PPI        *This,
    197   IN OUT  INT8                       *ArgumentBuffer OPTIONAL,
    198   IN OUT  UINTN                      *ArgumentBufferSize OPTIONAL,
    199   IN      BOOLEAN                    Periodic OPTIONAL,
    200   IN      UINTN                      ActivationInterval OPTIONAL
    201   )
    202 {
    203   INT8       Data;
    204   EFI_STATUS Status;
    205   //
    206   // Periodic SMI not supported.
    207   //
    208   if (Periodic) {
    209     DEBUG ((DEBUG_WARN, "Invalid parameter\n"));
    210     return EFI_INVALID_PARAMETER;
    211   }
    212 
    213   if (ArgumentBuffer == NULL) {
    214     Data = 0xFF;
    215   } else {
    216     if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) {
    217       return EFI_INVALID_PARAMETER;
    218     }
    219 
    220     Data = *ArgumentBuffer;
    221   }
    222   //
    223   // Clear any pending the APM SMI
    224   //
    225   Status = SmmClear ();
    226   if (EFI_ERROR (Status)) {
    227     return Status;
    228   }
    229 
    230   return SmmTrigger (Data);
    231 }
    232 
    233 /**
    234   Clears an SMI.
    235 
    236   @param  PeiServices         Describes the list of possible PEI Services.
    237   @param  This                Pointer to an instance of EFI_SMM_CONTROL_PPI
    238   @param  Periodic            TRUE to indicate a periodical SMI
    239 
    240   @return Return value from SmmClear()
    241 
    242 **/
    243 EFI_STATUS
    244 EFIAPI
    245 PeiDeactivate (
    246   IN  EFI_PEI_SERVICES            **PeiServices,
    247   IN  PEI_SMM_CONTROL_PPI         *This,
    248   IN  BOOLEAN                     Periodic OPTIONAL
    249   )
    250 {
    251   if (Periodic) {
    252     return EFI_INVALID_PARAMETER;
    253   }
    254   return SmmClear ();
    255 }
    256 
    257 /**
    258   This is the constructor for the SMM Control Ppi.
    259 
    260   This function installs EFI_SMM_CONTROL_PPI.
    261 
    262   @param   FileHandle       Handle of the file being invoked.
    263   @param   PeiServices      Describes the list of possible PEI Services.
    264 
    265   @retval EFI_UNSUPPORTED There's no Intel ICH on this platform
    266   @return The status returned from InstallPpi().
    267 
    268 --*/
    269 EFI_STATUS
    270 EFIAPI
    271 SmmControlPeiEntry (
    272   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    273   IN CONST EFI_PEI_SERVICES     **PeiServices
    274   )
    275 {
    276   EFI_STATUS  Status;
    277 
    278   Status      = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
    279   ASSERT_EFI_ERROR (Status);
    280 
    281   return Status;
    282 }
    283