1 /** @file
2   SMM Access2 Protocol on SMM Access Protocol Thunk driver.
3 
4   Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include "SmmAccess2OnSmmAccessThunk.h"
16 
17 EFI_SMM_ACCESS2_PROTOCOL gSmmAccess2 = {
18   SmmAccess2Open,
19   SmmAccess2Close,
20   SmmAccess2Lock,
21   SmmAccess2GetCapabilities,
22   FALSE,
23   FALSE
24 };
25 
26 EFI_SMM_ACCESS_PROTOCOL  *mSmmAccess;
27 UINTN                     mSmramRegionNumber;
28 
29 /**
30   Opens the SMRAM area to be accessible by a boot-service driver.
31 
32   This function "opens" SMRAM so that it is visible while not inside of SMM. The function should
33   return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM. The function
34   should return EFI_DEVICE_ERROR if the SMRAM configuration is locked.
35 
36   @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
37 
38   @retval EFI_SUCCESS       The operation was successful.
39   @retval EFI_UNSUPPORTED   The system does not support opening and closing of SMRAM.
40   @retval EFI_DEVICE_ERROR  SMRAM cannot be opened, perhaps because it is locked.
41 **/
42 EFI_STATUS
43 EFIAPI
SmmAccess2Open(IN EFI_SMM_ACCESS2_PROTOCOL * This)44 SmmAccess2Open (
45   IN EFI_SMM_ACCESS2_PROTOCOL  *This
46   )
47 {
48   EFI_STATUS Status;
49   UINTN      DescriptorIndex;
50 
51   ///
52   /// Open all SMRAM regions via SMM Access Protocol
53   ///
54 
55   Status = EFI_SUCCESS;
56   for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) {
57     Status = mSmmAccess->Open (mSmmAccess, DescriptorIndex);
58   }
59   if (!EFI_ERROR (Status)) {
60     gSmmAccess2.OpenState = TRUE;
61   }
62   return Status;
63 }
64 
65 /**
66   Inhibits access to the SMRAM.
67 
68   This function "closes" SMRAM so that it is not visible while outside of SMM. The function should
69   return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM.
70 
71   @param [in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
72 
73   @retval EFI_SUCCESS       The operation was successful.
74   @retval EFI_UNSUPPORTED   The system does not support opening and closing of SMRAM.
75   @retval EFI_DEVICE_ERROR  SMRAM cannot be closed.
76 **/
77 EFI_STATUS
78 EFIAPI
SmmAccess2Close(IN EFI_SMM_ACCESS2_PROTOCOL * This)79 SmmAccess2Close (
80   IN EFI_SMM_ACCESS2_PROTOCOL  *This
81   )
82 {
83   EFI_STATUS Status;
84   UINTN      DescriptorIndex;
85 
86   ///
87   /// Close all SMRAM regions via SMM Access Protocol
88   ///
89 
90   Status = EFI_SUCCESS;
91   for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) {
92     Status = mSmmAccess->Close (mSmmAccess, DescriptorIndex);
93   }
94   if (!EFI_ERROR (Status)) {
95     gSmmAccess2.OpenState = FALSE;
96   }
97   return Status;
98 }
99 
100 /**
101   Inhibits access to the SMRAM.
102 
103   This function prohibits access to the SMRAM region.  This function is usually implemented such
104   that it is a write-once operation.
105 
106   @param[in] This          The EFI_SMM_ACCESS2_PROTOCOL instance.
107 
108   @retval EFI_SUCCESS      The device was successfully locked.
109   @retval EFI_UNSUPPORTED  The system does not support locking of SMRAM.
110 **/
111 EFI_STATUS
112 EFIAPI
SmmAccess2Lock(IN EFI_SMM_ACCESS2_PROTOCOL * This)113 SmmAccess2Lock (
114   IN EFI_SMM_ACCESS2_PROTOCOL  *This
115   )
116 {
117   EFI_STATUS Status;
118   UINTN      DescriptorIndex;
119 
120   ///
121   /// Lock all SMRAM regions via SMM Access Protocol
122   ///
123 
124   Status = EFI_SUCCESS;
125   for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) {
126     Status = mSmmAccess->Lock (mSmmAccess, DescriptorIndex);
127   }
128   if (!EFI_ERROR (Status)) {
129     gSmmAccess2.LockState = TRUE;
130   }
131   return Status;
132 }
133 
134 /**
135   Queries the memory controller for the possible regions that will support SMRAM.
136 
137   @param[in]     This           The EFI_SMM_ACCESS2_PROTOCOL instance.
138   @param[in, out] SmramMapSize   A pointer to the size, in bytes, of the SmramMemoryMap buffer.
139   @param[in, out] SmramMap       A pointer to the buffer in which firmware places the current memory map.
140 
141   @retval EFI_SUCCESS           The chipset supported the given resource.
142   @retval EFI_BUFFER_TOO_SMALL  The SmramMap parameter was too small.  The current buffer size
143                                 needed to hold the memory map is returned in SmramMapSize.
144 **/
145 EFI_STATUS
146 EFIAPI
SmmAccess2GetCapabilities(IN CONST EFI_SMM_ACCESS2_PROTOCOL * This,IN OUT UINTN * SmramMapSize,IN OUT EFI_SMRAM_DESCRIPTOR * SmramMap)147 SmmAccess2GetCapabilities (
148   IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
149   IN OUT UINTN                       *SmramMapSize,
150   IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
151   )
152 {
153   return mSmmAccess->GetCapabilities (mSmmAccess, SmramMapSize, SmramMap);
154 }
155 
156 /**
157   Entry Point for SMM Access2 On SMM Access Thunk driver.
158 
159   @param[in] ImageHandle  Image handle of this driver.
160   @param[in] SystemTable  A Pointer to the EFI System Table.
161 
162   @retval EFI_SUCCESS  The entry point is executed successfully.
163   @retval other        Some error occurred when executing this entry point.
164 **/
165 EFI_STATUS
166 EFIAPI
SmmAccess2ThunkMain(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)167 SmmAccess2ThunkMain (
168   IN EFI_HANDLE        ImageHandle,
169   IN EFI_SYSTEM_TABLE  *SystemTable
170   )
171 {
172   EFI_STATUS            Status;
173   UINTN                 SmramMapSize;
174 
175   ///
176   /// Locate SMM Access Protocol
177   ///
178   Status = gBS->LocateProtocol (&gEfiSmmAccessProtocolGuid, NULL, (VOID **)&mSmmAccess);
179   ASSERT_EFI_ERROR (Status);
180 
181   ///
182   /// Calculate number of SMRAM regions
183   ///
184   SmramMapSize = 0;
185   Status = mSmmAccess->GetCapabilities (mSmmAccess, &SmramMapSize, NULL);
186   ASSERT (Status == EFI_BUFFER_TOO_SMALL);
187 
188   mSmramRegionNumber =  SmramMapSize/sizeof (EFI_SMRAM_DESCRIPTOR);
189   ASSERT (mSmramRegionNumber > 0);
190 
191   ///
192   /// Assume all SMRAM regions have consistent OPEN and LOCK states
193   ///
194   gSmmAccess2.OpenState = mSmmAccess->OpenState;
195   gSmmAccess2.LockState = mSmmAccess->LockState;
196 
197   ///
198   /// Publish PI SMM Access2 Protocol
199   ///
200   Status = gBS->InstallProtocolInterface (
201                   &ImageHandle,
202                   &gEfiSmmAccess2ProtocolGuid,
203                   EFI_NATIVE_INTERFACE,
204                   &gSmmAccess2
205                   );
206   return Status;
207 }
208 
209