1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 misc.c
15
16 Abstract:
17
18 --*/
19
20 #include "Tiano.h"
21 #include "pei.h"
22 #include "cpuio.h"
23 #include EFI_PPI_CONSUMER (PciCfg)
24 #include EFI_PPI_CONSUMER (PciCfg2)
25 #include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo)
26
27 //
28 // Modular variable used by common libiary in PEI phase
29 //
30 EFI_GUID mPeiCpuIoPpiGuid = PEI_CPU_IO_PPI_GUID;
31 #if (PI_SPECIFICATION_VERSION < 0x00010000)
32 EFI_GUID mPeiPciCfgPpiGuid = PEI_PCI_CFG_PPI_GUID;
33 PEI_PCI_CFG_PPI *PciCfgPpi = NULL;
34 #else
35 EFI_GUID mPeiPciCfgPpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID;
36 EFI_PEI_PCI_CFG2_PPI *PciCfgPpi = NULL;
37 #endif
38 EFI_PEI_SERVICES **mPeiServices = NULL;
39 PEI_CPU_IO_PPI *CpuIoPpi = NULL;
40
41 //
42 // Modular variable used by common libiary in DXE phase
43 //
44 EFI_SYSTEM_TABLE *mST = NULL;
45 EFI_BOOT_SERVICES *mBS = NULL;
46 EFI_RUNTIME_SERVICES *mRT = NULL;
47
48 EFI_STATUS
EfiInitializeCommonDriverLib(IN EFI_HANDLE ImageHandle,IN VOID * SystemTable)49 EfiInitializeCommonDriverLib (
50 IN EFI_HANDLE ImageHandle,
51 IN VOID *SystemTable
52 )
53 /*++
54
55 Routine Description:
56
57 Initialize lib function calling phase: PEI or DXE
58
59 Arguments:
60
61 ImageHandle - The firmware allocated handle for the EFI image.
62
63 SystemTable - A pointer to the EFI System Table.
64
65 Returns:
66
67 EFI_STATUS always returns EFI_SUCCESS
68
69 --*/
70 {
71 mPeiServices = NULL;
72 CpuIoPpi = NULL;
73 PciCfgPpi = NULL;
74
75 if (ImageHandle == NULL) {
76 //
77 // The function is called in PEI phase, use PEI interfaces
78 //
79 mPeiServices = (EFI_PEI_SERVICES **) SystemTable;
80 ASSERT (mPeiServices == NULL);
81
82 CpuIoPpi = (**mPeiServices).CpuIo;
83 PciCfgPpi = (**mPeiServices).PciCfg;
84
85 } else {
86 //
87 // ImageHandle is not NULL. The function is called in DXE phase
88 //
89 mST = SystemTable;
90 ASSERT (mST != NULL);
91
92 mBS = mST->BootServices;
93 mRT = mST->RuntimeServices;
94 ASSERT (mBS != NULL);
95 ASSERT (mRT != NULL);
96
97 //
98 // Should be at EFI_D_INFO, but lets us know things are running
99 //
100 DEBUG ((EFI_D_INFO, "EfiInitializeCommonDriverLib: Started in DXE\n"));
101 return EFI_SUCCESS;
102 }
103
104 return EFI_SUCCESS;
105 }
106
107
108 EFI_STATUS
EfiCommonIoWrite(IN UINT8 Width,IN UINTN Address,IN UINTN Count,IN OUT VOID * Buffer)109 EfiCommonIoWrite (
110 IN UINT8 Width,
111 IN UINTN Address,
112 IN UINTN Count,
113 IN OUT VOID *Buffer
114 )
115 /*++
116
117 Routine Description:
118
119 Io write operation.
120
121 Arguments:
122
123 Width - Width of write operation
124 Address - Start IO address to write
125 Count - Write count
126 Buffer - Buffer to write to the address
127
128 Returns:
129
130 Status code
131
132 --*/
133 {
134 EFI_STATUS Status;
135 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
136
137 if (mPeiServices != NULL) {
138 //
139 // The function is called in PEI phase, use PEI interfaces
140 //
141 Status = CpuIoPpi->Io.Write (
142 mPeiServices,
143 CpuIoPpi,
144 Width,
145 Address,
146 Count,
147 Buffer
148 );
149 } else {
150 //
151 // The function is called in DXE phase
152 //
153 Status = mBS->LocateProtocol (
154 &gEfiPciRootBridgeIoProtocolGuid,
155 NULL,
156 (VOID **) &RootBridgeIo
157 );
158 if (EFI_ERROR (Status)) {
159 return Status;
160 }
161
162 Status = RootBridgeIo->Io.Write (RootBridgeIo, Width, Address, Count, Buffer);
163 }
164
165 return Status;
166 }
167
168
169 EFI_STATUS
EfiCommonIoRead(IN UINT8 Width,IN UINTN Address,IN UINTN Count,IN OUT VOID * Buffer)170 EfiCommonIoRead (
171 IN UINT8 Width,
172 IN UINTN Address,
173 IN UINTN Count,
174 IN OUT VOID *Buffer
175 )
176 /*++
177
178 Routine Description:
179
180 Io read operation.
181
182 Arguments:
183
184 Width - Width of read operation
185 Address - Start IO address to read
186 Count - Read count
187 Buffer - Buffer to store result
188
189 Returns:
190
191 Status code
192
193 --*/
194 {
195 EFI_STATUS Status;
196 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
197
198 if (mPeiServices != NULL) {
199 //
200 // The function is called in PEI phase, use PEI interfaces
201 //
202 Status = CpuIoPpi->Io.Read (
203 mPeiServices,
204 CpuIoPpi,
205 Width,
206 Address,
207 Count,
208 Buffer
209 );
210 } else {
211 //
212 // The function is called in DXE phase
213 //
214 Status = mBS->LocateProtocol (
215 &gEfiPciRootBridgeIoProtocolGuid,
216 NULL,
217 (VOID **) &RootBridgeIo
218 );
219 if (EFI_ERROR (Status)) {
220 return Status;
221 }
222
223 Status = RootBridgeIo->Io.Read (RootBridgeIo, Width, Address, Count, Buffer);
224 }
225
226 return Status;
227 }
228
229
230 EFI_STATUS
EfiCommonPciWrite(IN UINT8 Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)231 EfiCommonPciWrite (
232 IN UINT8 Width,
233 IN UINT64 Address,
234 IN UINTN Count,
235 IN OUT VOID *Buffer
236 )
237 /*++
238
239 Routine Description:
240
241 Pci write operation
242
243 Arguments:
244
245 Width - Width of PCI write
246 Address - PCI address to write
247 Count - Write count
248 Buffer - Buffer to write to the address
249
250 Returns:
251
252 Status code
253
254 --*/
255 {
256 EFI_STATUS Status;
257 UINTN Index;
258 UINT8 *Buffer8;
259 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
260
261 if (mPeiServices != NULL) {
262 //
263 // The function is called in PEI phase, use PEI interfaces
264 //
265 Buffer8 = Buffer;
266 for (Index = 0; Index < Count; Index++) {
267 Status = PciCfgPpi->Write (
268 mPeiServices,
269 PciCfgPpi,
270 Width,
271 Address,
272 Buffer8
273 );
274
275 if (EFI_ERROR (Status)) {
276 return Status;
277 }
278
279 Buffer8 += Width;
280 }
281
282 } else {
283 //
284 // The function is called in DXE phase
285 //
286 Status = mBS->LocateProtocol (
287 &gEfiPciRootBridgeIoProtocolGuid,
288 NULL,
289 (VOID **) &RootBridgeIo
290 );
291 if (EFI_ERROR (Status)) {
292 return Status;
293 }
294
295 Status = RootBridgeIo->Pci.Write (
296 RootBridgeIo,
297 Width,
298 Address,
299 Count,
300 Buffer
301 );
302 }
303
304 return EFI_SUCCESS;
305 }
306
307 EFI_STATUS
EfiCommonPciRead(IN UINT8 Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)308 EfiCommonPciRead (
309 IN UINT8 Width,
310 IN UINT64 Address,
311 IN UINTN Count,
312 IN OUT VOID *Buffer
313 )
314 /*++
315
316 Routine Description:
317
318 Pci read operation
319
320 Arguments:
321
322 Width - Width of PCI read
323 Address - PCI address to read
324 Count - Read count
325 Buffer - Output buffer for the read
326
327 Returns:
328
329 Status code
330
331 --*/
332 {
333 EFI_STATUS Status;
334 UINTN Index;
335 UINT8 *Buffer8;
336 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
337
338 if (mPeiServices != NULL) {
339 //
340 // The function is called in PEI phase, use PEI interfaces
341 //
342 Buffer8 = Buffer;
343 for (Index = 0; Index < Count; Index++) {
344 Status = PciCfgPpi->Read (
345 mPeiServices,
346 PciCfgPpi,
347 Width,
348 Address,
349 Buffer8
350 );
351
352 if (EFI_ERROR (Status)) {
353 return Status;
354 }
355
356 Buffer8 += Width;
357 }
358
359 } else {
360 //
361 // The function is called in DXE phase
362 //
363 Status = mBS->LocateProtocol (
364 &gEfiPciRootBridgeIoProtocolGuid,
365 NULL,
366 (VOID **) &RootBridgeIo
367 );
368 if (EFI_ERROR (Status)) {
369 return Status;
370 }
371
372 Status = RootBridgeIo->Pci.Read (
373 RootBridgeIo,
374 Width,
375 Address,
376 Count,
377 Buffer
378 );
379 }
380
381 return EFI_SUCCESS;
382 }
383