1 /** @file
2   Reset Architectural Protocol implementation
3 
4   Copyright (c) 2006 - 2012, 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 WatchdogData.
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 
94 **/
95 VOID
96 EFIAPI
ResetSystem(IN EFI_RESET_TYPE ResetType,IN EFI_STATUS ResetStatus,IN UINTN DataSize,IN VOID * ResetData OPTIONAL)97 ResetSystem (
98   IN EFI_RESET_TYPE   ResetType,
99   IN EFI_STATUS       ResetStatus,
100   IN UINTN            DataSize,
101   IN VOID             *ResetData OPTIONAL
102   )
103 {
104   EFI_STATUS    Status;
105   UINTN         Size;
106   UINTN         CapsuleDataPtr;
107 
108   //
109   // Indicate reset system runtime service is called.
110   //
111   REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM));
112 
113   switch (ResetType) {
114   case EfiResetWarm:
115 
116     //
117     //Check if there are pending capsules to process
118     //
119     Size = sizeof (CapsuleDataPtr);
120     Status =  EfiGetVariable (
121                  EFI_CAPSULE_VARIABLE_NAME,
122                  &gEfiCapsuleVendorGuid,
123                  NULL,
124                  &Size,
125                  (VOID *) &CapsuleDataPtr
126                  );
127 
128     if (Status == EFI_SUCCESS) {
129       //
130       //Process capsules across a system reset.
131       //
132       DoS3();
133     }
134 
135     ResetWarm ();
136 
137     break;
138 
139  case EfiResetCold:
140     ResetCold ();
141     break;
142 
143   case EfiResetShutdown:
144     ResetShutdown ();
145     return ;
146 
147   default:
148     return ;
149   }
150 
151   //
152   // Given we should have reset getting here would be bad
153   //
154   ASSERT (FALSE);
155 }
156