1 /** @file
2   HII Config Access protocol implementation of TREE configuration module.
3   NOTE: This module is only for reference only, each platform should have its own setup page.
4 
5 Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution.  The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10 
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include "TrEEConfigImpl.h"
17 #include <Library/PcdLib.h>
18 #include <Library/Tpm2CommandLib.h>
19 #include <Guid/TpmInstance.h>
20 
21 TPM_INSTANCE_ID  mTpmInstanceId[TPM_DEVICE_MAX + 1] = TPM_INSTANCE_ID_LIST;
22 
23 TREE_CONFIG_PRIVATE_DATA         mTrEEConfigPrivateDateTemplate = {
24   TREE_CONFIG_PRIVATE_DATA_SIGNATURE,
25   {
26     TrEEExtractConfig,
27     TrEERouteConfig,
28     TrEECallback
29   }
30 };
31 
32 HII_VENDOR_DEVICE_PATH          mTrEEHiiVendorDevicePath = {
33   {
34     {
35       HARDWARE_DEVICE_PATH,
36       HW_VENDOR_DP,
37       {
38         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
39         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
40       }
41     },
42     TREE_CONFIG_FORM_SET_GUID
43   },
44   {
45     END_DEVICE_PATH_TYPE,
46     END_ENTIRE_DEVICE_PATH_SUBTYPE,
47     {
48       (UINT8) (END_DEVICE_PATH_LENGTH),
49       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
50     }
51   }
52 };
53 
54 /**
55   This function allows a caller to extract the current configuration for one
56   or more named elements from the target driver.
57 
58   @param[in]   This              Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
59   @param[in]   Request           A null-terminated Unicode string in
60                                  <ConfigRequest> format.
61   @param[out]  Progress          On return, points to a character in the Request
62                                  string. Points to the string's null terminator if
63                                  request was successful. Points to the most recent
64                                  '&' before the first failing name/value pair (or
65                                  the beginning of the string if the failure is in
66                                  the first name/value pair) if the request was not
67                                  successful.
68   @param[out]  Results           A null-terminated Unicode string in
69                                  <ConfigAltResp> format which has all values filled
70                                  in for the names in the Request string. String to
71                                  be allocated by the called function.
72 
73   @retval EFI_SUCCESS            The Results is filled with the requested values.
74   @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
75   @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
76   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
77                                  driver.
78 
79 **/
80 EFI_STATUS
81 EFIAPI
TrEEExtractConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Request,OUT EFI_STRING * Progress,OUT EFI_STRING * Results)82 TrEEExtractConfig (
83   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL        *This,
84   IN CONST EFI_STRING                            Request,
85        OUT EFI_STRING                            *Progress,
86        OUT EFI_STRING                            *Results
87   )
88 {
89   if (Progress == NULL || Results == NULL) {
90     return EFI_INVALID_PARAMETER;
91   }
92 
93   *Progress = Request;
94   return EFI_NOT_FOUND;
95 }
96 
97 /**
98   Save TPM request to variable space.
99 
100   @param[in] PpRequest             Physical Presence request command.
101 
102   @retval    EFI_SUCCESS           The operation is finished successfully.
103   @retval    Others                Other errors as indicated.
104 
105 **/
106 EFI_STATUS
SaveTrEEPpRequest(IN UINT8 PpRequest)107 SaveTrEEPpRequest (
108   IN UINT8                         PpRequest
109   )
110 {
111   EFI_STATUS                       Status;
112   UINTN                            DataSize;
113   EFI_TREE_PHYSICAL_PRESENCE       PpData;
114 
115   //
116   // Save TPM command to variable.
117   //
118   DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
119   Status = gRT->GetVariable (
120                   TREE_PHYSICAL_PRESENCE_VARIABLE,
121                   &gEfiTrEEPhysicalPresenceGuid,
122                   NULL,
123                   &DataSize,
124                   &PpData
125                   );
126   if (EFI_ERROR (Status)) {
127     return Status;
128   }
129 
130   PpData.PPRequest = PpRequest;
131   Status = gRT->SetVariable (
132                   TREE_PHYSICAL_PRESENCE_VARIABLE,
133                   &gEfiTrEEPhysicalPresenceGuid,
134                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
135                   DataSize,
136                   &PpData
137                   );
138   if (EFI_ERROR(Status)) {
139     return Status;
140   }
141 
142   return EFI_SUCCESS;
143 }
144 
145 /**
146   This function processes the results of changes in configuration.
147 
148   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
149   @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>
150                                  format.
151   @param[out] Progress           A pointer to a string filled in with the offset of
152                                  the most recent '&' before the first failing
153                                  name/value pair (or the beginning of the string if
154                                  the failure is in the first name/value pair) or
155                                  the terminating NULL if all was successful.
156 
157   @retval EFI_SUCCESS            The Results is processed successfully.
158   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
159   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
160                                  driver.
161 
162 **/
163 EFI_STATUS
164 EFIAPI
TrEERouteConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Configuration,OUT EFI_STRING * Progress)165 TrEERouteConfig (
166   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
167   IN CONST EFI_STRING                          Configuration,
168        OUT EFI_STRING                          *Progress
169   )
170 {
171   if (Configuration == NULL || Progress == NULL) {
172     return EFI_INVALID_PARAMETER;
173   }
174 
175   return EFI_NOT_FOUND;
176 }
177 
178 /**
179   This function processes the results of changes in configuration.
180 
181   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
182   @param[in]  Action             Specifies the type of action taken by the browser.
183   @param[in]  QuestionId         A unique value which is sent to the original
184                                  exporting driver so that it can identify the type
185                                  of data to expect.
186   @param[in]  Type               The type of value for the question.
187   @param[in]  Value              A pointer to the data being sent to the original
188                                  exporting driver.
189   @param[out] ActionRequest      On return, points to the action requested by the
190                                  callback function.
191 
192   @retval EFI_SUCCESS            The callback successfully handled the action.
193   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
194                                  variable and its data.
195   @retval EFI_DEVICE_ERROR       The variable could not be saved.
196   @retval EFI_UNSUPPORTED        The specified Action is not supported by the
197                                  callback.
198 
199 **/
200 EFI_STATUS
201 EFIAPI
TrEECallback(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN EFI_BROWSER_ACTION Action,IN EFI_QUESTION_ID QuestionId,IN UINT8 Type,IN EFI_IFR_TYPE_VALUE * Value,OUT EFI_BROWSER_ACTION_REQUEST * ActionRequest)202 TrEECallback (
203   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
204   IN     EFI_BROWSER_ACTION                    Action,
205   IN     EFI_QUESTION_ID                       QuestionId,
206   IN     UINT8                                 Type,
207   IN     EFI_IFR_TYPE_VALUE                    *Value,
208      OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
209   )
210 {
211   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
212     return EFI_INVALID_PARAMETER;
213   }
214 
215   if (Action == EFI_BROWSER_ACTION_CHANGED) {
216     if (QuestionId == KEY_TPM_DEVICE) {
217       return EFI_SUCCESS;
218     }
219     if (QuestionId == KEY_TPM2_OPERATION) {
220       return SaveTrEEPpRequest (Value->u8);
221     }
222   }
223 
224   return EFI_UNSUPPORTED;
225 }
226 
227 /**
228   This function publish the TREE configuration Form for TPM device.
229 
230   @param[in, out]  PrivateData   Points to TREE configuration private data.
231 
232   @retval EFI_SUCCESS            HII Form is installed for this network device.
233   @retval EFI_OUT_OF_RESOURCES   Not enough resource for HII Form installation.
234   @retval Others                 Other errors as indicated.
235 
236 **/
237 EFI_STATUS
InstallTrEEConfigForm(IN OUT TREE_CONFIG_PRIVATE_DATA * PrivateData)238 InstallTrEEConfigForm (
239   IN OUT TREE_CONFIG_PRIVATE_DATA  *PrivateData
240   )
241 {
242   EFI_STATUS                      Status;
243   EFI_HII_HANDLE                  HiiHandle;
244   EFI_HANDLE                      DriverHandle;
245   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
246 
247   DriverHandle = NULL;
248   ConfigAccess = &PrivateData->ConfigAccess;
249   Status = gBS->InstallMultipleProtocolInterfaces (
250                   &DriverHandle,
251                   &gEfiDevicePathProtocolGuid,
252                   &mTrEEHiiVendorDevicePath,
253                   &gEfiHiiConfigAccessProtocolGuid,
254                   ConfigAccess,
255                   NULL
256                   );
257   if (EFI_ERROR (Status)) {
258     return Status;
259   }
260 
261   PrivateData->DriverHandle = DriverHandle;
262 
263   //
264   // Publish the HII package list
265   //
266   HiiHandle = HiiAddPackages (
267                 &gTrEEConfigFormSetGuid,
268                 DriverHandle,
269                 TrEEConfigDxeStrings,
270                 TrEEConfigBin,
271                 NULL
272                 );
273   if (HiiHandle == NULL) {
274     gBS->UninstallMultipleProtocolInterfaces (
275            DriverHandle,
276            &gEfiDevicePathProtocolGuid,
277            &mTrEEHiiVendorDevicePath,
278            &gEfiHiiConfigAccessProtocolGuid,
279            ConfigAccess,
280            NULL
281            );
282 
283     return EFI_OUT_OF_RESOURCES;
284   }
285 
286   PrivateData->HiiHandle = HiiHandle;
287 
288   //
289   // Update static data
290   //
291   switch (PrivateData->TpmDeviceDetected) {
292   case TPM_DEVICE_NULL:
293     HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"Not Found", NULL);
294     break;
295   case TPM_DEVICE_1_2:
296     HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL);
297     break;
298   case TPM_DEVICE_2_0_DTPM:
299     HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"TPM 2.0 (DTPM)", NULL);
300     break;
301   default:
302     HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"Unknown", NULL);
303     break;
304   }
305 
306   return EFI_SUCCESS;
307 }
308 
309 /**
310   This function removes TREE configuration Form.
311 
312   @param[in, out]  PrivateData   Points to TREE configuration private data.
313 
314 **/
315 VOID
UninstallTrEEConfigForm(IN OUT TREE_CONFIG_PRIVATE_DATA * PrivateData)316 UninstallTrEEConfigForm (
317   IN OUT TREE_CONFIG_PRIVATE_DATA    *PrivateData
318   )
319 {
320   //
321   // Uninstall HII package list
322   //
323   if (PrivateData->HiiHandle != NULL) {
324     HiiRemovePackages (PrivateData->HiiHandle);
325     PrivateData->HiiHandle = NULL;
326   }
327 
328   //
329   // Uninstall HII Config Access Protocol
330   //
331   if (PrivateData->DriverHandle != NULL) {
332     gBS->UninstallMultipleProtocolInterfaces (
333            PrivateData->DriverHandle,
334            &gEfiDevicePathProtocolGuid,
335            &mTrEEHiiVendorDevicePath,
336            &gEfiHiiConfigAccessProtocolGuid,
337            &PrivateData->ConfigAccess,
338            NULL
339            );
340     PrivateData->DriverHandle = NULL;
341   }
342 
343   FreePool (PrivateData);
344 }
345