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