1 /** @file
2 Implementation of Legacy Region 2 Protocol based on Framework Legacy Region Protocol.
3
4 Intel's Framework Legacy Region Protocol is replaced by Legacy Region 2 Protocol in PI 1.2.
5 This module produces PI Legacy Region 2 Protocol on top of Framework Legacy Region Protocol.
6
7 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17
18 #include "LegacyRegion2OnLegacyRegionThunk.h"
19
20 EFI_HANDLE mLegacyRegion2Handle = NULL;
21
22 EFI_LEGACY_REGION_PROTOCOL *mLegacyRegion;
23
24 EFI_LEGACY_REGION2_PROTOCOL mLegacyRegion2 = {
25 LegacyRegion2Decode,
26 LegacyRegion2Lock,
27 LegacyRegion2BootLock,
28 LegacyRegion2Unlock,
29 LegacyRegionGetInfo
30 };
31
32 /**
33 Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region.
34
35 If the On parameter evaluates to TRUE, this function enables memory reads in the address range
36 Start to (Start + Length - 1).
37 If the On parameter evaluates to FALSE, this function disables memory reads in the address range
38 Start to (Start + Length - 1).
39
40 @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
41 @param Start[in] The beginning of the physical address of the region whose attributes
42 should be modified.
43 @param Length[in] The number of bytes of memory whose attributes should be modified.
44 The actual number of bytes modified may be greater than the number
45 specified.
46 @param Granularity[out] The number of bytes in the last region affected. This may be less
47 than the total number of bytes affected if the starting address
48 was not aligned to a region's starting address or if the length
49 was greater than the number of bytes in the first region.
50 @param On[in] Decode / Non-Decode flag.
51
52 @retval EFI_SUCCESS The region's attributes were successfully modified.
53 @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
54
55 **/
56 EFI_STATUS
57 EFIAPI
LegacyRegion2Decode(IN EFI_LEGACY_REGION2_PROTOCOL * This,IN UINT32 Start,IN UINT32 Length,OUT UINT32 * Granularity,IN BOOLEAN * On)58 LegacyRegion2Decode (
59 IN EFI_LEGACY_REGION2_PROTOCOL *This,
60 IN UINT32 Start,
61 IN UINT32 Length,
62 OUT UINT32 *Granularity,
63 IN BOOLEAN *On
64 )
65 {
66 if ((Start < 0xC0000) || ((Start + Length - 1) > 0xFFFFF)) {
67 return EFI_INVALID_PARAMETER;
68 }
69
70 ASSERT (Granularity != NULL);
71 *Granularity = 0;
72
73 return mLegacyRegion->Decode (
74 mLegacyRegion,
75 Start,
76 Length,
77 On
78 );
79 }
80
81 /**
82 Modify the hardware to disallow memory writes in a region.
83
84 This function changes the attributes of a memory range to not allow writes.
85
86 @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
87 @param Start[in] The beginning of the physical address of the region whose
88 attributes should be modified.
89 @param Length[in] The number of bytes of memory whose attributes should be modified.
90 The actual number of bytes modified may be greater than the number
91 specified.
92 @param Granularity[out] The number of bytes in the last region affected. This may be less
93 than the total number of bytes affected if the starting address was
94 not aligned to a region's starting address or if the length was
95 greater than the number of bytes in the first region.
96
97 @retval EFI_SUCCESS The region's attributes were successfully modified.
98 @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
99
100 **/
101 EFI_STATUS
102 EFIAPI
LegacyRegion2Lock(IN EFI_LEGACY_REGION2_PROTOCOL * This,IN UINT32 Start,IN UINT32 Length,OUT UINT32 * Granularity)103 LegacyRegion2Lock (
104 IN EFI_LEGACY_REGION2_PROTOCOL *This,
105 IN UINT32 Start,
106 IN UINT32 Length,
107 OUT UINT32 *Granularity
108 )
109 {
110 if ((Start < 0xC0000) || ((Start + Length - 1) > 0xFFFFF)) {
111 return EFI_INVALID_PARAMETER;
112 }
113
114 ASSERT (Granularity != NULL);
115
116 return mLegacyRegion->Lock (
117 mLegacyRegion,
118 Start,
119 Length,
120 Granularity
121 );
122 }
123
124 /**
125 Modify the hardware to disallow memory attribute changes in a region.
126
127 This function makes the attributes of a region read only. Once a region is boot-locked with this
128 function, the read and write attributes of that region cannot be changed until a power cycle has
129 reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect.
130
131 @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
132 @param Start[in] The beginning of the physical address of the region whose
133 attributes should be modified.
134 @param Length[in] The number of bytes of memory whose attributes should be modified.
135 The actual number of bytes modified may be greater than the number
136 specified.
137 @param Granularity[out] The number of bytes in the last region affected. This may be less
138 than the total number of bytes affected if the starting address was
139 not aligned to a region's starting address or if the length was
140 greater than the number of bytes in the first region.
141
142 @retval EFI_SUCCESS The region's attributes were successfully modified.
143 @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
144 @retval EFI_UNSUPPORTED The chipset does not support locking the configuration registers in
145 a way that will not affect memory regions outside the legacy memory
146 region.
147
148 **/
149 EFI_STATUS
150 EFIAPI
LegacyRegion2BootLock(IN EFI_LEGACY_REGION2_PROTOCOL * This,IN UINT32 Start,IN UINT32 Length,OUT UINT32 * Granularity)151 LegacyRegion2BootLock (
152 IN EFI_LEGACY_REGION2_PROTOCOL *This,
153 IN UINT32 Start,
154 IN UINT32 Length,
155 OUT UINT32 *Granularity
156 )
157 {
158 if ((Start < 0xC0000) || ((Start + Length - 1) > 0xFFFFF)) {
159 return EFI_INVALID_PARAMETER;
160 }
161
162 //
163 // PI Legacy Region 2 Protocol and Framework Legacy Region Protocol have different
164 // semantic of BootLock() API, so we cannot thunk to Framework Legacy Region Protocol
165 // to produce the functionality of PI version. In addition, this functionality is
166 // chipset dependent, so here we return EFI_UNSUPPORTED, which is a valid return status
167 // code specified by PI spec.
168 //
169 return EFI_UNSUPPORTED;
170 }
171
172 /**
173 Modify the hardware to allow memory writes in a region.
174
175 This function changes the attributes of a memory range to allow writes.
176
177 @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
178 @param Start[in] The beginning of the physical address of the region whose
179 attributes should be modified.
180 @param Length[in] The number of bytes of memory whose attributes should be modified.
181 The actual number of bytes modified may be greater than the number
182 specified.
183 @param Granularity[out] The number of bytes in the last region affected. This may be less
184 than the total number of bytes affected if the starting address was
185 not aligned to a region's starting address or if the length was
186 greater than the number of bytes in the first region.
187
188 @retval EFI_SUCCESS The region's attributes were successfully modified.
189 @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
190
191 **/
192 EFI_STATUS
193 EFIAPI
LegacyRegion2Unlock(IN EFI_LEGACY_REGION2_PROTOCOL * This,IN UINT32 Start,IN UINT32 Length,OUT UINT32 * Granularity)194 LegacyRegion2Unlock (
195 IN EFI_LEGACY_REGION2_PROTOCOL *This,
196 IN UINT32 Start,
197 IN UINT32 Length,
198 OUT UINT32 *Granularity
199 )
200 {
201 if ((Start < 0xC0000) || ((Start + Length - 1) > 0xFFFFF)) {
202 return EFI_INVALID_PARAMETER;
203 }
204
205 ASSERT (Granularity != NULL);
206
207 return mLegacyRegion->UnLock (
208 mLegacyRegion,
209 Start,
210 Length,
211 Granularity
212 );
213 }
214
215 /**
216 Get region information for the attributes of the Legacy Region.
217
218 This function is used to discover the granularity of the attributes for the memory in the legacy
219 region. Each attribute may have a different granularity and the granularity may not be the same
220 for all memory ranges in the legacy region.
221
222 @param This[in] Indicates the EFI_LEGACY_REGION2_PROTOCOL instance.
223 @param DescriptorCount[out] The number of region descriptor entries returned in the Descriptor
224 buffer.
225 @param Descriptor[out] A pointer to a pointer used to return a buffer where the legacy
226 region information is deposited. This buffer will contain a list of
227 DescriptorCount number of region descriptors. This function will
228 provide the memory for the buffer.
229
230 @retval EFI_SUCCESS The information structure was returned.
231 @retval EFI_UNSUPPORTED This function is not supported.
232
233 **/
234 EFI_STATUS
235 EFIAPI
LegacyRegionGetInfo(IN EFI_LEGACY_REGION2_PROTOCOL * This,OUT UINT32 * DescriptorCount,OUT EFI_LEGACY_REGION_DESCRIPTOR ** Descriptor)236 LegacyRegionGetInfo (
237 IN EFI_LEGACY_REGION2_PROTOCOL *This,
238 OUT UINT32 *DescriptorCount,
239 OUT EFI_LEGACY_REGION_DESCRIPTOR **Descriptor
240 )
241 {
242 return EFI_UNSUPPORTED;
243 }
244
245 /**
246 The user Entry Point for module LegacyRegionDxe. The user code starts with this function.
247
248 @param[in] ImageHandle The firmware allocated handle for the EFI image.
249 @param[in] SystemTable A pointer to the EFI System Table.
250
251 @retval EFI_SUCCESS The entry point is executed successfully.
252
253 **/
254 EFI_STATUS
255 EFIAPI
LegacyRegion2OnLegacyRegionThunkInitialize(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)256 LegacyRegion2OnLegacyRegionThunkInitialize (
257 IN EFI_HANDLE ImageHandle,
258 IN EFI_SYSTEM_TABLE *SystemTable
259 )
260 {
261 EFI_STATUS Status;
262
263 //
264 // Make sure the Legacy Region 2 Protocol is not already installed in the system
265 //
266 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiLegacyRegion2ProtocolGuid);
267
268 //
269 // Locate and cache Framework Legacy Region Protocol.
270 //
271 Status = gBS->LocateProtocol (
272 &gEfiLegacyRegionProtocolGuid,
273 NULL,
274 (VOID **) &mLegacyRegion
275 );
276 ASSERT_EFI_ERROR (Status);
277
278 //
279 // Install the protocol on a new handle.
280 //
281 Status = gBS->InstallMultipleProtocolInterfaces (
282 &mLegacyRegion2Handle,
283 &gEfiLegacyRegion2ProtocolGuid, &mLegacyRegion2,
284 NULL
285 );
286 ASSERT_EFI_ERROR (Status);
287
288 return Status;
289 }
290