1 /** @file
2   Implement TPM1.2 Startup related command.
3 
4 Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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 <PiPei.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/Tpm12DeviceLib.h>
20 #include <Library/DebugLib.h>
21 
22 #pragma pack(1)
23 
24 typedef struct {
25   TPM_RQU_COMMAND_HDR   Hdr;
26   TPM_STARTUP_TYPE      TpmSt;
27 } TPM_CMD_START_UP;
28 
29 #pragma pack()
30 
31 /**
32   Send Startup command to TPM1.2.
33 
34   @param TpmSt           Startup Type.
35 
36   @retval EFI_SUCCESS      Operation completed successfully.
37   @retval EFI_DEVICE_ERROR Unexpected device behavior.
38 **/
39 EFI_STATUS
40 EFIAPI
Tpm12Startup(IN TPM_STARTUP_TYPE TpmSt)41 Tpm12Startup (
42   IN TPM_STARTUP_TYPE  TpmSt
43   )
44 {
45   EFI_STATUS           Status;
46   TPM_CMD_START_UP     Command;
47   TPM_RSP_COMMAND_HDR  Response;
48   UINT32               Length;
49 
50   //
51   // send Tpm command TPM_ORD_Startup
52   //
53   Command.Hdr.tag       = SwapBytes16 (TPM_TAG_RQU_COMMAND);
54   Command.Hdr.paramSize = SwapBytes32 (sizeof (Command));
55   Command.Hdr.ordinal   = SwapBytes32 (TPM_ORD_Startup);
56   Command.TpmSt         = SwapBytes16 (TpmSt);
57   Length = sizeof (Response);
58   Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
59   if (EFI_ERROR (Status)) {
60     return Status;
61   }
62   switch (SwapBytes32(Response.returnCode)) {
63   case TPM_SUCCESS:
64     DEBUG ((DEBUG_INFO, "TPM12Startup: TPM_SUCCESS\n"));
65     return EFI_SUCCESS;
66   case TPM_INVALID_POSTINIT:
67     // In warm reset, TPM may response TPM_INVALID_POSTINIT
68     DEBUG ((DEBUG_INFO, "TPM12Startup: TPM_INVALID_POSTINIT\n"));
69     return EFI_SUCCESS;
70   default:
71     return EFI_DEVICE_ERROR;
72   }
73 }
74 
75 /**
76   Send SaveState command to TPM1.2.
77 
78   @retval EFI_SUCCESS      Operation completed successfully.
79   @retval EFI_DEVICE_ERROR Unexpected device behavior.
80 **/
81 EFI_STATUS
82 EFIAPI
Tpm12SaveState(VOID)83 Tpm12SaveState (
84   VOID
85   )
86 {
87   EFI_STATUS           Status;
88   TPM_RQU_COMMAND_HDR  Command;
89   TPM_RSP_COMMAND_HDR  Response;
90   UINT32               Length;
91 
92   //
93   // send Tpm command TPM_ORD_SaveState
94   //
95   Command.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
96   Command.paramSize  = SwapBytes32 (sizeof (Command));
97   Command.ordinal    = SwapBytes32 (TPM_ORD_SaveState);
98   Length = sizeof (Response);
99   Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
100   if (EFI_ERROR (Status)) {
101     return Status;
102   }
103   switch (SwapBytes32 (Response.returnCode)) {
104   case TPM_SUCCESS:
105     return EFI_SUCCESS;
106   default:
107     return EFI_DEVICE_ERROR;
108   }
109 }
110