• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Support ResetSystem Runtime call using PSCI calls
3 
4   Note: A similar library is implemented in
5   ArmPkg/Library/ArmPsciResetSystemLib. Similar issues might
6   exist in this implementation too.
7 
8   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
9   Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
10   Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
11 
12   This program and the accompanying materials
13   are licensed and made available under the terms and conditions of the BSD License
14   which accompanies this distribution.  The full text of the license may be found at
15   http://opensource.org/licenses/bsd-license.php
16 
17   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 **/
21 
22 #include <PiDxe.h>
23 
24 #include <Library/BaseLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/EfiResetSystemLib.h>
27 #include <Library/ArmSmcLib.h>
28 #include <Library/ArmHvcLib.h>
29 #include <Library/UefiBootServicesTableLib.h>
30 
31 #include <IndustryStandard/ArmStdSmc.h>
32 
33 #include <Protocol/FdtClient.h>
34 
35 STATIC UINT32 mArmPsciMethod;
36 
37 RETURN_STATUS
38 EFIAPI
ArmPsciResetSystemLibConstructor(VOID)39 ArmPsciResetSystemLibConstructor (
40   VOID
41   )
42 {
43   EFI_STATUS            Status;
44   FDT_CLIENT_PROTOCOL   *FdtClient;
45   CONST VOID            *Prop;
46 
47   Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
48                   (VOID **)&FdtClient);
49   ASSERT_EFI_ERROR (Status);
50 
51   Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,psci-0.2",
52                         "method", &Prop, NULL);
53   if (EFI_ERROR (Status)) {
54     return Status;
55   }
56 
57   if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
58     mArmPsciMethod = 1;
59   } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
60     mArmPsciMethod = 2;
61   } else {
62     DEBUG ((EFI_D_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__,
63       Prop));
64     return EFI_NOT_FOUND;
65   }
66   return EFI_SUCCESS;
67 }
68 
69 /**
70   Resets the entire platform.
71 
72   @param  ResetType             The type of reset to perform.
73   @param  ResetStatus           The status code for the reset.
74   @param  DataSize              The size, in bytes, of WatchdogData.
75   @param  ResetData             For a ResetType of EfiResetCold, EfiResetWarm, or
76                                 EfiResetShutdown the data buffer starts with a Null-terminated
77                                 Unicode string, optionally followed by additional binary data.
78 
79 **/
80 EFI_STATUS
81 EFIAPI
LibResetSystem(IN EFI_RESET_TYPE ResetType,IN EFI_STATUS ResetStatus,IN UINTN DataSize,IN CHAR16 * ResetData OPTIONAL)82 LibResetSystem (
83   IN EFI_RESET_TYPE   ResetType,
84   IN EFI_STATUS       ResetStatus,
85   IN UINTN            DataSize,
86   IN CHAR16           *ResetData OPTIONAL
87   )
88 {
89   ARM_SMC_ARGS ArmSmcArgs;
90   ARM_HVC_ARGS ArmHvcArgs;
91 
92   switch (ResetType) {
93 
94   case EfiResetPlatformSpecific:
95     // Map the platform specific reset as reboot
96   case EfiResetWarm:
97     // Map a warm reset into a cold reset
98   case EfiResetCold:
99     // Send a PSCI 0.2 SYSTEM_RESET command
100     ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
101     ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
102     break;
103   case EfiResetShutdown:
104     // Send a PSCI 0.2 SYSTEM_OFF command
105     ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
106     ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
107     break;
108   default:
109     ASSERT (FALSE);
110     return EFI_UNSUPPORTED;
111   }
112 
113   switch (mArmPsciMethod) {
114   case 1:
115     ArmCallHvc (&ArmHvcArgs);
116     break;
117 
118   case 2:
119     ArmCallSmc (&ArmSmcArgs);
120     break;
121 
122   default:
123     DEBUG ((EFI_D_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));
124     return EFI_UNSUPPORTED;
125   }
126 
127   // We should never be here
128   DEBUG ((EFI_D_ERROR, "%a: PSCI Reset failed\n", __FUNCTION__));
129   CpuDeadLoop ();
130   return EFI_UNSUPPORTED;
131 }
132 
133 /**
134   Initialize any infrastructure required for LibResetSystem () to function.
135 
136   @param  ImageHandle   The firmware allocated handle for the EFI image.
137   @param  SystemTable   A pointer to the EFI System Table.
138 
139   @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
140 
141 **/
142 EFI_STATUS
143 EFIAPI
LibInitializeResetSystem(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)144 LibInitializeResetSystem (
145   IN EFI_HANDLE        ImageHandle,
146   IN EFI_SYSTEM_TABLE  *SystemTable
147   )
148 {
149   return EFI_SUCCESS;
150 }
151