• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
SmmClear(VOID)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
SmmTrigger(IN UINT8 Data)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
PeiActivate(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_SMM_CONTROL_PPI * This,IN OUT INT8 * ArgumentBuffer OPTIONAL,IN OUT UINTN * ArgumentBufferSize OPTIONAL,IN BOOLEAN Periodic OPTIONAL,IN UINTN ActivationInterval OPTIONAL)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
PeiDeactivate(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_SMM_CONTROL_PPI * This,IN BOOLEAN Periodic OPTIONAL)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
SmmControlPeiEntry(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES ** PeiServices)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