1 /** @file
2   Reset Architectural Protocol implementation
3 
4   Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
5 
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 "ResetSystem.h"
17 
18 //
19 // The handle onto which the Reset Architectural Protocol is installed
20 //
21 EFI_HANDLE  mResetHandle = NULL;
22 
23 /**
24   The driver's entry point.
25 
26   It initializes the Reset Architectural Protocol.
27 
28   @param[in] ImageHandle  The firmware allocated handle for the EFI image.
29   @param[in] SystemTable  A pointer to the EFI System Table.
30 
31   @retval EFI_SUCCESS     The entry point is executed successfully.
32   @retval other           Cannot install ResetArch protocol.
33 
34 **/
35 EFI_STATUS
36 EFIAPI
InitializeResetSystem(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)37 InitializeResetSystem (
38   IN EFI_HANDLE        ImageHandle,
39   IN EFI_SYSTEM_TABLE  *SystemTable
40   )
41 {
42   EFI_STATUS  Status;
43 
44   //
45   // Make sure the Reset Architectural Protocol is not already installed in the system
46   //
47   ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);
48 
49   //
50   // Hook the runtime service table
51   //
52   gRT->ResetSystem = ResetSystem;
53 
54   //
55   // Now install the Reset RT AP on a new handle
56   //
57   Status = gBS->InstallMultipleProtocolInterfaces (
58                   &mResetHandle,
59                   &gEfiResetArchProtocolGuid,
60                   NULL,
61                   NULL
62                   );
63   ASSERT_EFI_ERROR (Status);
64 
65   return Status;
66 }
67 
68 /**
69   Put the system into S3 power state.
70 **/
71 VOID
DoS3(VOID)72 DoS3 (
73   VOID
74   )
75 {
76   EnterS3WithImmediateWake ();
77 
78   //
79   // Should not return
80   //
81   CpuDeadLoop ();
82 }
83 
84 /**
85   Resets the entire platform.
86 
87   @param[in] ResetType          The type of reset to perform.
88   @param[in] ResetStatus        The status code for the reset.
89   @param[in] DataSize           The size, in bytes, of ResetData.
90   @param[in] ResetData          For a ResetType of EfiResetCold, EfiResetWarm, or
91                                 EfiResetShutdown the data buffer starts with a Null-terminated
92                                 string, optionally followed by additional binary data.
93                                 The string is a description that the caller may use to further
94                                 indicate the reason for the system reset. ResetData is only
95                                 valid if ResetStatus is something other than EFI_SUCCESS
96                                 unless the ResetType is EfiResetPlatformSpecific
97                                 where a minimum amount of ResetData is always required.
98 **/
99 VOID
100 EFIAPI
ResetSystem(IN EFI_RESET_TYPE ResetType,IN EFI_STATUS ResetStatus,IN UINTN DataSize,IN VOID * ResetData OPTIONAL)101 ResetSystem (
102   IN EFI_RESET_TYPE   ResetType,
103   IN EFI_STATUS       ResetStatus,
104   IN UINTN            DataSize,
105   IN VOID             *ResetData OPTIONAL
106   )
107 {
108   EFI_STATUS    Status;
109   UINTN         Size;
110   UINTN         CapsuleDataPtr;
111 
112   //
113   // Indicate reset system runtime service is called.
114   //
115   REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM));
116 
117   switch (ResetType) {
118   case EfiResetWarm:
119 
120     //
121     //Check if there are pending capsules to process
122     //
123     Size = sizeof (CapsuleDataPtr);
124     Status =  EfiGetVariable (
125                  EFI_CAPSULE_VARIABLE_NAME,
126                  &gEfiCapsuleVendorGuid,
127                  NULL,
128                  &Size,
129                  (VOID *) &CapsuleDataPtr
130                  );
131 
132     if (Status == EFI_SUCCESS) {
133       //
134       //Process capsules across a system reset.
135       //
136       DoS3();
137     }
138 
139     ResetWarm ();
140 
141     break;
142 
143  case EfiResetCold:
144     ResetCold ();
145     break;
146 
147   case EfiResetShutdown:
148     ResetShutdown ();
149     return ;
150 
151   case EfiResetPlatformSpecific:
152     ResetPlatformSpecific (DataSize, ResetData);
153     return;
154 
155   default:
156     return ;
157   }
158 
159   //
160   // Given we should have reset getting here would be bad
161   //
162   ASSERT (FALSE);
163 }
164