]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/PeiPciLibPciCfg2/PciLib.c
Synchronized Macro definition of GET_GUID_HOB_DATA_SIZE, GET_GUID_HOB_DATA, END_OF_H...
[mirror_edk2.git] / MdePkg / Library / PeiPciLibPciCfg2 / PciLib.c
CommitLineData
1a3eaf06 1/** @file\r
2 PCI Library using PCI CFG2 PPI.\r
3\r
4 Copyright (c) 2007 - 2008, Intel Corporation All rights\r
5 reserved. This program and the accompanying materials are\r
6 licensed and made available under the terms and conditions of\r
7 the BSD License which accompanies this distribution. The full\r
8 text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10 \r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PiPei.h>\r
17\r
18#include <Ppi/PciCfg2.h>\r
19\r
20#include <Library/PciLib.h>\r
21#include <Library/BaseLib.h>\r
22#include <Library/PeiServicesTablePointerLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/PeiServicesLib.h>\r
25\r
26/**\r
27 Assert the validity of a PCI address. A valid PCI address should contain 1's\r
28 only in the low 28 bits.\r
29\r
30 @param A The address to validate.\r
31 @param M Additional bits to assert to be zero.\r
32\r
33**/\r
34#define ASSERT_INVALID_PCI_ADDRESS(A,M) \\r
35 ASSERT (((A) & (~0xfffffff | (M))) == 0)\r
36\r
37/**\r
38 Translate PCI Lib address into format of PCI CFG2 PPI.\r
39\r
40 @param A Address that encodes the PCI Bus, Device, Function and\r
41 Register.\r
42\r
43**/\r
44#define PCI_TO_PCICFG2_ADDRESS(A) \\r
e43e4b3e 45 ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))\r
1a3eaf06 46\r
47/**\r
48 Internal worker function to read a PCI configuration register.\r
49\r
50 This function wraps EFI_PEI_PCI_CFG2_PPI.Read() service.\r
51 It reads and returns the PCI configuration register specified by Address,\r
52 the width of data is specified by Width.\r
53\r
54 @param Address Address that encodes the PCI Bus, Device, Function and\r
55 Register.\r
56 @param Width Width of data to read\r
57\r
58 @return The value read from the PCI configuration register.\r
59\r
60**/\r
61UINT32\r
62PeiPciLibPciCfg2ReadWorker (\r
63 IN UINTN Address,\r
64 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width\r
65 )\r
66{\r
67 EFI_STATUS Status;\r
68 UINT32 Data;\r
69 CONST EFI_PEI_PCI_CFG2_PPI *PciCfg2Ppi;\r
43fe5cdc 70 UINT64 PciCfg2Address;\r
1a3eaf06 71\r
72 Status = PeiServicesLocatePpi (&gEfiPciCfg2PpiGuid, 0, NULL, (VOID **) &PciCfg2Ppi);\r
73 ASSERT_EFI_ERROR (Status);\r
74 ASSERT (PciCfg2Ppi != NULL);\r
75\r
43fe5cdc 76 PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);\r
1a3eaf06 77 PciCfg2Ppi->Read (\r
78 GetPeiServicesTablePointer (),\r
79 PciCfg2Ppi,\r
80 Width,\r
43fe5cdc 81 PciCfg2Address,\r
1a3eaf06 82 &Data\r
83 );\r
84\r
85 return Data;\r
86}\r
87\r
88/**\r
89 Internal worker function to writes a PCI configuration register.\r
90\r
91 This function wraps EFI_PEI_PCI_CFG2_PPI.Write() service.\r
92 It writes the PCI configuration register specified by Address with the\r
93 value specified by Data. The width of data is specifed by Width.\r
94 Data is returned.\r
95\r
96 @param Address Address that encodes the PCI Bus, Device, Function and\r
97 Register.\r
98 @param Width Width of data to write\r
99 @param Data The value to write.\r
100\r
101 @return The value written to the PCI configuration register.\r
102\r
103**/\r
104UINT32\r
105PeiPciLibPciCfg2WriteWorker (\r
106 IN UINTN Address,\r
107 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
108 IN UINT32 Data\r
109 )\r
110{\r
111 EFI_STATUS Status;\r
112 CONST EFI_PEI_PCI_CFG2_PPI *PciCfg2Ppi;\r
43fe5cdc 113 UINT64 PciCfg2Address;\r
1a3eaf06 114\r
115 Status = PeiServicesLocatePpi (&gEfiPciCfg2PpiGuid, 0, NULL, (VOID **) &PciCfg2Ppi);\r
116 ASSERT_EFI_ERROR (Status);\r
117 ASSERT (PciCfg2Ppi != NULL);\r
118\r
43fe5cdc 119 PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);\r
1a3eaf06 120 PciCfg2Ppi->Write (\r
121 GetPeiServicesTablePointer (),\r
122 PciCfg2Ppi,\r
123 Width,\r
43fe5cdc 124 PciCfg2Address,\r
1a3eaf06 125 &Data\r
126 );\r
127\r
128 return Data;\r
129}\r
130\r
3e3ae634 131/**\r
132 Register a PCI device so PCI configuration registers may be accessed after \r
133 SetVirtualAddressMap().\r
134 \r
135 If Address > 0x0FFFFFFF, then ASSERT().\r
136\r
137 @param Address Address that encodes the PCI Bus, Device, Function and\r
138 Register.\r
139 \r
140 @retval RETURN_SUCCESS The PCI device was registered for runtime access.\r
141 @retval RETURN_UNSUPPORTED An attempt was made to call this function \r
142 after ExitBootServices().\r
143 @retval RETURN_UNSUPPORTED The resources required to access the PCI device\r
144 at runtime could not be mapped.\r
145 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to\r
146 complete the registration.\r
147\r
148**/\r
149RETURN_STATUS\r
150EFIAPI\r
151PciRegisterForRuntimeAccess (\r
152 IN UINTN Address\r
153 )\r
154{\r
155 return RETURN_UNSUPPORTED;\r
156}\r
157\r
1a3eaf06 158/**\r
159 Reads an 8-bit PCI configuration register.\r
160\r
161 Reads and returns the 8-bit PCI configuration register specified by Address.\r
162 This function must guarantee that all PCI read and write operations are\r
163 serialized.\r
164\r
165 If Address > 0x0FFFFFFF, then ASSERT().\r
166\r
167 @param Address Address that encodes the PCI Bus, Device, Function and\r
168 Register.\r
169\r
170 @return The value read from the PCI configuration register.\r
171\r
172**/\r
173UINT8\r
174EFIAPI\r
175PciRead8 (\r
176 IN UINTN Address\r
177 )\r
178{\r
179 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
180\r
181 return (UINT8) PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint8);\r
182}\r
183\r
184/**\r
185 Writes an 8-bit PCI configuration register.\r
186\r
187 Writes the 8-bit PCI configuration register specified by Address with the\r
188 value specified by Value. Value is returned. This function must guarantee\r
189 that all PCI read and write operations are serialized.\r
190\r
191 If Address > 0x0FFFFFFF, then ASSERT().\r
192\r
193 @param Address Address that encodes the PCI Bus, Device, Function and\r
194 Register.\r
195 @param Data The value to write.\r
196\r
197 @return The value written to the PCI configuration register.\r
198\r
199**/\r
200UINT8\r
201EFIAPI\r
202PciWrite8 (\r
203 IN UINTN Address,\r
204 IN UINT8 Data\r
205 )\r
206{\r
207 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
208\r
209 return (UINT8) PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint8, Data);\r
210}\r
211\r
212/**\r
213 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with\r
214 an 8-bit value.\r
215\r
216 Reads the 8-bit PCI configuration register specified by Address, performs a\r
217 bitwise inclusive OR between the read result and the value specified by\r
218 OrData, and writes the result to the 8-bit PCI configuration register\r
219 specified by Address. The value written to the PCI configuration register is\r
220 returned. This function must guarantee that all PCI read and write operations\r
221 are serialized.\r
222\r
223 If Address > 0x0FFFFFFF, then ASSERT().\r
224\r
225 @param Address Address that encodes the PCI Bus, Device, Function and\r
226 Register.\r
227 @param OrData The value to OR with the PCI configuration register.\r
228\r
229 @return The value written back to the PCI configuration register.\r
230\r
231**/\r
232UINT8\r
233EFIAPI\r
234PciOr8 (\r
235 IN UINTN Address,\r
236 IN UINT8 OrData\r
237 )\r
238{\r
239 return PciWrite8 (Address, (UINT8) (PciRead8 (Address) | OrData));\r
240}\r
241\r
242/**\r
243 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
244 value.\r
245\r
246 Reads the 8-bit PCI configuration register specified by Address, performs a\r
247 bitwise AND between the read result and the value specified by AndData, and\r
248 writes the result to the 8-bit PCI configuration register specified by\r
249 Address. The value written to the PCI configuration register is returned.\r
250 This function must guarantee that all PCI read and write operations are\r
251 serialized.\r
252\r
253 If Address > 0x0FFFFFFF, then ASSERT().\r
254\r
255 @param Address Address that encodes the PCI Bus, Device, Function and\r
256 Register.\r
257 @param AndData The value to AND with the PCI configuration register.\r
258\r
259 @return The value written back to the PCI configuration register.\r
260\r
261**/\r
262UINT8\r
263EFIAPI\r
264PciAnd8 (\r
265 IN UINTN Address,\r
266 IN UINT8 AndData\r
267 )\r
268{\r
269 return PciWrite8 (Address, (UINT8) (PciRead8 (Address) & AndData));\r
270}\r
271\r
272/**\r
273 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
274 value, followed a bitwise inclusive OR with another 8-bit value.\r
275\r
276 Reads the 8-bit PCI configuration register specified by Address, performs a\r
277 bitwise AND between the read result and the value specified by AndData,\r
278 performs a bitwise inclusive OR between the result of the AND operation and\r
279 the value specified by OrData, and writes the result to the 8-bit PCI\r
280 configuration register specified by Address. The value written to the PCI\r
281 configuration register is returned. This function must guarantee that all PCI\r
282 read and write operations are serialized.\r
283\r
284 If Address > 0x0FFFFFFF, then ASSERT().\r
285\r
286 @param Address Address that encodes the PCI Bus, Device, Function and\r
287 Register.\r
288 @param AndData The value to AND with the PCI configuration register.\r
289 @param OrData The value to OR with the result of the AND operation.\r
290\r
291 @return The value written back to the PCI configuration register.\r
292\r
293**/\r
294UINT8\r
295EFIAPI\r
296PciAndThenOr8 (\r
297 IN UINTN Address,\r
298 IN UINT8 AndData,\r
299 IN UINT8 OrData\r
300 )\r
301{\r
302 return PciWrite8 (Address, (UINT8) ((PciRead8 (Address) & AndData) | OrData));\r
303}\r
304\r
305/**\r
306 Reads a bit field of a PCI configuration register.\r
307\r
308 Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
309 specified by the StartBit and the EndBit. The value of the bit field is\r
310 returned.\r
311\r
312 If Address > 0x0FFFFFFF, then ASSERT().\r
313 If StartBit is greater than 7, then ASSERT().\r
314 If EndBit is greater than 7, then ASSERT().\r
315 If EndBit is less than StartBit, then ASSERT().\r
316\r
317 @param Address PCI configuration register to read.\r
318 @param StartBit The ordinal of the least significant bit in the bit field.\r
319 Range 0..7.\r
320 @param EndBit The ordinal of the most significant bit in the bit field.\r
321 Range 0..7.\r
322\r
323 @return The value of the bit field read from the PCI configuration register.\r
324\r
325**/\r
326UINT8\r
327EFIAPI\r
328PciBitFieldRead8 (\r
329 IN UINTN Address,\r
330 IN UINTN StartBit,\r
331 IN UINTN EndBit\r
332 )\r
333{\r
334 return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);\r
335}\r
336\r
337/**\r
338 Writes a bit field to a PCI configuration register.\r
339\r
340 Writes Value to the bit field of the PCI configuration register. The bit\r
341 field is specified by the StartBit and the EndBit. All other bits in the\r
342 destination PCI configuration register are preserved. The new value of the\r
343 8-bit register is returned.\r
344\r
345 If Address > 0x0FFFFFFF, then ASSERT().\r
346 If StartBit is greater than 7, then ASSERT().\r
347 If EndBit is greater than 7, then ASSERT().\r
348 If EndBit is less than StartBit, then ASSERT().\r
349\r
350 @param Address PCI configuration register to write.\r
351 @param StartBit The ordinal of the least significant bit in the bit field.\r
352 Range 0..7.\r
353 @param EndBit The ordinal of the most significant bit in the bit field.\r
354 Range 0..7.\r
355 @param Value New value of the bit field.\r
356\r
357 @return The value written back to the PCI configuration register.\r
358\r
359**/\r
360UINT8\r
361EFIAPI\r
362PciBitFieldWrite8 (\r
363 IN UINTN Address,\r
364 IN UINTN StartBit,\r
365 IN UINTN EndBit,\r
366 IN UINT8 Value\r
367 )\r
368{\r
369 return PciWrite8 (\r
370 Address,\r
371 BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)\r
372 );\r
373}\r
374\r
375/**\r
376 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
377 writes the result back to the bit field in the 8-bit port.\r
378\r
379 Reads the 8-bit PCI configuration register specified by Address, performs a\r
380 bitwise inclusive OR between the read result and the value specified by\r
381 OrData, and writes the result to the 8-bit PCI configuration register\r
382 specified by Address. The value written to the PCI configuration register is\r
383 returned. This function must guarantee that all PCI read and write operations\r
384 are serialized. Extra left bits in OrData are stripped.\r
385\r
386 If Address > 0x0FFFFFFF, then ASSERT().\r
387 If StartBit is greater than 7, then ASSERT().\r
388 If EndBit is greater than 7, then ASSERT().\r
389 If EndBit is less than StartBit, then ASSERT().\r
390\r
391 @param Address PCI configuration register to write.\r
392 @param StartBit The ordinal of the least significant bit in the bit field.\r
393 Range 0..7.\r
394 @param EndBit The ordinal of the most significant bit in the bit field.\r
395 Range 0..7.\r
396 @param OrData The value to OR with the PCI configuration register.\r
397\r
398 @return The value written back to the PCI configuration register.\r
399\r
400**/\r
401UINT8\r
402EFIAPI\r
403PciBitFieldOr8 (\r
404 IN UINTN Address,\r
405 IN UINTN StartBit,\r
406 IN UINTN EndBit,\r
407 IN UINT8 OrData\r
408 )\r
409{\r
410 return PciWrite8 (\r
411 Address,\r
412 BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)\r
413 );\r
414}\r
415\r
416/**\r
417 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
418 AND, and writes the result back to the bit field in the 8-bit register.\r
419\r
420 Reads the 8-bit PCI configuration register specified by Address, performs a\r
421 bitwise AND between the read result and the value specified by AndData, and\r
422 writes the result to the 8-bit PCI configuration register specified by\r
423 Address. The value written to the PCI configuration register is returned.\r
424 This function must guarantee that all PCI read and write operations are\r
425 serialized. Extra left bits in AndData are stripped.\r
426\r
427 If Address > 0x0FFFFFFF, then ASSERT().\r
428 If StartBit is greater than 7, then ASSERT().\r
429 If EndBit is greater than 7, then ASSERT().\r
430 If EndBit is less than StartBit, then ASSERT().\r
431\r
432 @param Address PCI configuration register to write.\r
433 @param StartBit The ordinal of the least significant bit in the bit field.\r
434 Range 0..7.\r
435 @param EndBit The ordinal of the most significant bit in the bit field.\r
436 Range 0..7.\r
437 @param AndData The value to AND with the PCI configuration register.\r
438\r
439 @return The value written back to the PCI configuration register.\r
440\r
441**/\r
442UINT8\r
443EFIAPI\r
444PciBitFieldAnd8 (\r
445 IN UINTN Address,\r
446 IN UINTN StartBit,\r
447 IN UINTN EndBit,\r
448 IN UINT8 AndData\r
449 )\r
450{\r
451 return PciWrite8 (\r
452 Address,\r
453 BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)\r
454 );\r
455}\r
456\r
457/**\r
458 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
459 bitwise inclusive OR, and writes the result back to the bit field in the\r
460 8-bit port.\r
461\r
462 Reads the 8-bit PCI configuration register specified by Address, performs a\r
463 bitwise AND followed by a bitwise inclusive OR between the read result and\r
464 the value specified by AndData, and writes the result to the 8-bit PCI\r
465 configuration register specified by Address. The value written to the PCI\r
466 configuration register is returned. This function must guarantee that all PCI\r
467 read and write operations are serialized. Extra left bits in both AndData and\r
468 OrData are stripped.\r
469\r
470 If Address > 0x0FFFFFFF, then ASSERT().\r
471 If StartBit is greater than 7, then ASSERT().\r
472 If EndBit is greater than 7, then ASSERT().\r
473 If EndBit is less than StartBit, then ASSERT().\r
474\r
475 @param Address PCI configuration register to write.\r
476 @param StartBit The ordinal of the least significant bit in the bit field.\r
477 Range 0..7.\r
478 @param EndBit The ordinal of the most significant bit in the bit field.\r
479 Range 0..7.\r
480 @param AndData The value to AND with the PCI configuration register.\r
481 @param OrData The value to OR with the result of the AND operation.\r
482\r
483 @return The value written back to the PCI configuration register.\r
484\r
485**/\r
486UINT8\r
487EFIAPI\r
488PciBitFieldAndThenOr8 (\r
489 IN UINTN Address,\r
490 IN UINTN StartBit,\r
491 IN UINTN EndBit,\r
492 IN UINT8 AndData,\r
493 IN UINT8 OrData\r
494 )\r
495{\r
496 return PciWrite8 (\r
497 Address,\r
498 BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)\r
499 );\r
500}\r
501\r
502/**\r
503 Reads a 16-bit PCI configuration register.\r
504\r
505 Reads and returns the 16-bit PCI configuration register specified by Address.\r
506 This function must guarantee that all PCI read and write operations are\r
507 serialized.\r
508\r
509 If Address > 0x0FFFFFFF, then ASSERT().\r
510 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
511\r
512 @param Address Address that encodes the PCI Bus, Device, Function and\r
513 Register.\r
514\r
9638ba6d 515 @return The read value from the PCI configuration register.\r
1a3eaf06 516\r
517**/\r
518UINT16\r
519EFIAPI\r
520PciRead16 (\r
521 IN UINTN Address\r
522 )\r
523{\r
524 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
525\r
526 return (UINT16) PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint16);\r
527}\r
528\r
529/**\r
530 Writes a 16-bit PCI configuration register.\r
531\r
532 Writes the 16-bit PCI configuration register specified by Address with the\r
533 value specified by Value. Value is returned. This function must guarantee\r
534 that all PCI read and write operations are serialized.\r
535\r
536 If Address > 0x0FFFFFFF, then ASSERT().\r
537 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
538\r
539 @param Address Address that encodes the PCI Bus, Device, Function and\r
540 Register.\r
9638ba6d 541 @param Value The value to write.\r
1a3eaf06 542\r
543 @return The value written to the PCI configuration register.\r
544\r
545**/\r
546UINT16\r
547EFIAPI\r
548PciWrite16 (\r
549 IN UINTN Address,\r
550 IN UINT16 Data\r
551 )\r
552{\r
553 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
554\r
555 return (UINT16) PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint16, Data);\r
556}\r
557\r
558/**\r
559 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with\r
560 a 16-bit value.\r
561\r
562 Reads the 16-bit PCI configuration register specified by Address, performs a\r
563 bitwise inclusive OR between the read result and the value specified by\r
564 OrData, and writes the result to the 16-bit PCI configuration register\r
565 specified by Address. The value written to the PCI configuration register is\r
566 returned. This function must guarantee that all PCI read and write operations\r
567 are serialized.\r
568\r
569 If Address > 0x0FFFFFFF, then ASSERT().\r
570 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
571\r
572 @param Address Address that encodes the PCI Bus, Device, Function and\r
573 Register.\r
574 @param OrData The value to OR with the PCI configuration register.\r
575\r
576 @return The value written back to the PCI configuration register.\r
577\r
578**/\r
579UINT16\r
580EFIAPI\r
581PciOr16 (\r
582 IN UINTN Address,\r
583 IN UINT16 OrData\r
584 )\r
585{\r
586 return PciWrite16 (Address, (UINT16) (PciRead16 (Address) | OrData));\r
587}\r
588\r
589/**\r
590 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
591 value.\r
592\r
593 Reads the 16-bit PCI configuration register specified by Address, performs a\r
594 bitwise AND between the read result and the value specified by AndData, and\r
595 writes the result to the 16-bit PCI configuration register specified by\r
596 Address. The value written to the PCI configuration register is returned.\r
597 This function must guarantee that all PCI read and write operations are\r
598 serialized.\r
599\r
600 If Address > 0x0FFFFFFF, then ASSERT().\r
601 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
602\r
603 @param Address Address that encodes the PCI Bus, Device, Function and\r
604 Register.\r
605 @param AndData The value to AND with the PCI configuration register.\r
606\r
607 @return The value written back to the PCI configuration register.\r
608\r
609**/\r
610UINT16\r
611EFIAPI\r
612PciAnd16 (\r
613 IN UINTN Address,\r
614 IN UINT16 AndData\r
615 )\r
616{\r
617 return PciWrite16 (Address, (UINT16) (PciRead16 (Address) & AndData));\r
618}\r
619\r
620/**\r
621 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
622 value, followed a bitwise inclusive OR with another 16-bit value.\r
623\r
624 Reads the 16-bit PCI configuration register specified by Address, performs a\r
625 bitwise AND between the read result and the value specified by AndData,\r
626 performs a bitwise inclusive OR between the result of the AND operation and\r
627 the value specified by OrData, and writes the result to the 16-bit PCI\r
628 configuration register specified by Address. The value written to the PCI\r
629 configuration register is returned. This function must guarantee that all PCI\r
630 read and write operations are serialized.\r
631\r
632 If Address > 0x0FFFFFFF, then ASSERT().\r
633 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
634\r
635 @param Address Address that encodes the PCI Bus, Device, Function and\r
636 Register.\r
637 @param AndData The value to AND with the PCI configuration register.\r
638 @param OrData The value to OR with the result of the AND operation.\r
639\r
640 @return The value written back to the PCI configuration register.\r
641\r
642**/\r
643UINT16\r
644EFIAPI\r
645PciAndThenOr16 (\r
646 IN UINTN Address,\r
647 IN UINT16 AndData,\r
648 IN UINT16 OrData\r
649 )\r
650{\r
651 return PciWrite16 (Address, (UINT16) ((PciRead16 (Address) & AndData) | OrData));\r
652}\r
653\r
654/**\r
655 Reads a bit field of a PCI configuration register.\r
656\r
657 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
658 specified by the StartBit and the EndBit. The value of the bit field is\r
659 returned.\r
660\r
661 If Address > 0x0FFFFFFF, then ASSERT().\r
662 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
663 If StartBit is greater than 15, then ASSERT().\r
664 If EndBit is greater than 15, then ASSERT().\r
665 If EndBit is less than StartBit, then ASSERT().\r
666\r
667 @param Address PCI configuration register to read.\r
668 @param StartBit The ordinal of the least significant bit in the bit field.\r
669 Range 0..15.\r
670 @param EndBit The ordinal of the most significant bit in the bit field.\r
671 Range 0..15.\r
672\r
673 @return The value of the bit field read from the PCI configuration register.\r
674\r
675**/\r
676UINT16\r
677EFIAPI\r
678PciBitFieldRead16 (\r
679 IN UINTN Address,\r
680 IN UINTN StartBit,\r
681 IN UINTN EndBit\r
682 )\r
683{\r
684 return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);\r
685}\r
686\r
687/**\r
688 Writes a bit field to a PCI configuration register.\r
689\r
690 Writes Value to the bit field of the PCI configuration register. The bit\r
691 field is specified by the StartBit and the EndBit. All other bits in the\r
692 destination PCI configuration register are preserved. The new value of the\r
693 16-bit register is returned.\r
694\r
695 If Address > 0x0FFFFFFF, then ASSERT().\r
696 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
697 If StartBit is greater than 15, then ASSERT().\r
698 If EndBit is greater than 15, then ASSERT().\r
699 If EndBit is less than StartBit, then ASSERT().\r
700\r
701 @param Address PCI configuration register to write.\r
702 @param StartBit The ordinal of the least significant bit in the bit field.\r
703 Range 0..15.\r
704 @param EndBit The ordinal of the most significant bit in the bit field.\r
705 Range 0..15.\r
706 @param Value New value of the bit field.\r
707\r
708 @return The value written back to the PCI configuration register.\r
709\r
710**/\r
711UINT16\r
712EFIAPI\r
713PciBitFieldWrite16 (\r
714 IN UINTN Address,\r
715 IN UINTN StartBit,\r
716 IN UINTN EndBit,\r
717 IN UINT16 Value\r
718 )\r
719{\r
720 return PciWrite16 (\r
721 Address,\r
722 BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)\r
723 );\r
724}\r
725\r
726/**\r
727 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r
728 writes the result back to the bit field in the 16-bit port.\r
729\r
730 Reads the 16-bit PCI configuration register specified by Address, performs a\r
731 bitwise inclusive OR between the read result and the value specified by\r
732 OrData, and writes the result to the 16-bit PCI configuration register\r
733 specified by Address. The value written to the PCI configuration register is\r
734 returned. This function must guarantee that all PCI read and write operations\r
735 are serialized. Extra left bits in OrData are stripped.\r
736\r
737 If Address > 0x0FFFFFFF, then ASSERT().\r
738 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
739 If StartBit is greater than 15, then ASSERT().\r
740 If EndBit is greater than 15, then ASSERT().\r
741 If EndBit is less than StartBit, then ASSERT().\r
742\r
743 @param Address PCI configuration register to write.\r
744 @param StartBit The ordinal of the least significant bit in the bit field.\r
745 Range 0..15.\r
746 @param EndBit The ordinal of the most significant bit in the bit field.\r
747 Range 0..15.\r
748 @param OrData The value to OR with the PCI configuration register.\r
749\r
750 @return The value written back to the PCI configuration register.\r
751\r
752**/\r
753UINT16\r
754EFIAPI\r
755PciBitFieldOr16 (\r
756 IN UINTN Address,\r
757 IN UINTN StartBit,\r
758 IN UINTN EndBit,\r
759 IN UINT16 OrData\r
760 )\r
761{\r
762 return PciWrite16 (\r
763 Address,\r
764 BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)\r
765 );\r
766}\r
767\r
768/**\r
769 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
770 AND, and writes the result back to the bit field in the 16-bit register.\r
771\r
772 Reads the 16-bit PCI configuration register specified by Address, performs a\r
773 bitwise AND between the read result and the value specified by AndData, and\r
774 writes the result to the 16-bit PCI configuration register specified by\r
775 Address. The value written to the PCI configuration register is returned.\r
776 This function must guarantee that all PCI read and write operations are\r
777 serialized. Extra left bits in AndData are stripped.\r
778\r
779 If Address > 0x0FFFFFFF, then ASSERT().\r
780 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
781 If StartBit is greater than 15, then ASSERT().\r
782 If EndBit is greater than 15, then ASSERT().\r
783 If EndBit is less than StartBit, then ASSERT().\r
784\r
785 @param Address PCI configuration register to write.\r
786 @param StartBit The ordinal of the least significant bit in the bit field.\r
787 Range 0..15.\r
788 @param EndBit The ordinal of the most significant bit in the bit field.\r
789 Range 0..15.\r
790 @param AndData The value to AND with the PCI configuration register.\r
791\r
792 @return The value written back to the PCI configuration register.\r
793\r
794**/\r
795UINT16\r
796EFIAPI\r
797PciBitFieldAnd16 (\r
798 IN UINTN Address,\r
799 IN UINTN StartBit,\r
800 IN UINTN EndBit,\r
801 IN UINT16 AndData\r
802 )\r
803{\r
804 return PciWrite16 (\r
805 Address,\r
806 BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)\r
807 );\r
808}\r
809\r
810/**\r
811 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
812 bitwise inclusive OR, and writes the result back to the bit field in the\r
813 16-bit port.\r
814\r
815 Reads the 16-bit PCI configuration register specified by Address, performs a\r
816 bitwise AND followed by a bitwise inclusive OR between the read result and\r
817 the value specified by AndData, and writes the result to the 16-bit PCI\r
818 configuration register specified by Address. The value written to the PCI\r
819 configuration register is returned. This function must guarantee that all PCI\r
820 read and write operations are serialized. Extra left bits in both AndData and\r
821 OrData are stripped.\r
822\r
823 If Address > 0x0FFFFFFF, then ASSERT().\r
824 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
825 If StartBit is greater than 15, then ASSERT().\r
826 If EndBit is greater than 15, then ASSERT().\r
827 If EndBit is less than StartBit, then ASSERT().\r
828\r
829 @param Address PCI configuration register to write.\r
830 @param StartBit The ordinal of the least significant bit in the bit field.\r
831 Range 0..15.\r
832 @param EndBit The ordinal of the most significant bit in the bit field.\r
833 Range 0..15.\r
834 @param AndData The value to AND with the PCI configuration register.\r
835 @param OrData The value to OR with the result of the AND operation.\r
836\r
837 @return The value written back to the PCI configuration register.\r
838\r
839**/\r
840UINT16\r
841EFIAPI\r
842PciBitFieldAndThenOr16 (\r
843 IN UINTN Address,\r
844 IN UINTN StartBit,\r
845 IN UINTN EndBit,\r
846 IN UINT16 AndData,\r
847 IN UINT16 OrData\r
848 )\r
849{\r
850 return PciWrite16 (\r
851 Address,\r
852 BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)\r
853 );\r
854}\r
855\r
856/**\r
857 Reads a 32-bit PCI configuration register.\r
858\r
859 Reads and returns the 32-bit PCI configuration register specified by Address.\r
860 This function must guarantee that all PCI read and write operations are\r
861 serialized.\r
862\r
863 If Address > 0x0FFFFFFF, then ASSERT().\r
864 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
865\r
866 @param Address Address that encodes the PCI Bus, Device, Function and\r
867 Register.\r
868\r
9638ba6d 869 @return The read value from the PCI configuration register.\r
1a3eaf06 870\r
871**/\r
872UINT32\r
873EFIAPI\r
874PciRead32 (\r
875 IN UINTN Address\r
876 )\r
877{\r
878 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
879\r
880 return PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint32);\r
881}\r
882\r
883/**\r
884 Writes a 32-bit PCI configuration register.\r
885\r
886 Writes the 32-bit PCI configuration register specified by Address with the\r
887 value specified by Value. Value is returned. This function must guarantee\r
888 that all PCI read and write operations are serialized.\r
889\r
890 If Address > 0x0FFFFFFF, then ASSERT().\r
891 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
892\r
893 @param Address Address that encodes the PCI Bus, Device, Function and\r
894 Register.\r
9638ba6d 895 @param Value The value to write.\r
1a3eaf06 896\r
897 @return The value written to the PCI configuration register.\r
898\r
899**/\r
900UINT32\r
901EFIAPI\r
902PciWrite32 (\r
903 IN UINTN Address,\r
904 IN UINT32 Data\r
905 )\r
906{\r
907 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
908\r
909 return PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint32, Data);\r
910}\r
911\r
912/**\r
913 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with\r
914 a 32-bit value.\r
915\r
916 Reads the 32-bit PCI configuration register specified by Address, performs a\r
917 bitwise inclusive OR between the read result and the value specified by\r
918 OrData, and writes the result to the 32-bit PCI configuration register\r
919 specified by Address. The value written to the PCI configuration register is\r
920 returned. This function must guarantee that all PCI read and write operations\r
921 are serialized.\r
922\r
923 If Address > 0x0FFFFFFF, then ASSERT().\r
924 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
925\r
926 @param Address Address that encodes the PCI Bus, Device, Function and\r
927 Register.\r
928 @param OrData The value to OR with the PCI configuration register.\r
929\r
930 @return The value written back to the PCI configuration register.\r
931\r
932**/\r
933UINT32\r
934EFIAPI\r
935PciOr32 (\r
936 IN UINTN Address,\r
937 IN UINT32 OrData\r
938 )\r
939{\r
940 return PciWrite32 (Address, PciRead32 (Address) | OrData);\r
941}\r
942\r
943/**\r
944 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
945 value.\r
946\r
947 Reads the 32-bit PCI configuration register specified by Address, performs a\r
948 bitwise AND between the read result and the value specified by AndData, and\r
949 writes the result to the 32-bit PCI configuration register specified by\r
950 Address. The value written to the PCI configuration register is returned.\r
951 This function must guarantee that all PCI read and write operations are\r
952 serialized.\r
953\r
954 If Address > 0x0FFFFFFF, then ASSERT().\r
955 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
956\r
957 @param Address Address that encodes the PCI Bus, Device, Function and\r
958 Register.\r
959 @param AndData The value to AND with the PCI configuration register.\r
960\r
961 @return The value written back to the PCI configuration register.\r
962\r
963**/\r
964UINT32\r
965EFIAPI\r
966PciAnd32 (\r
967 IN UINTN Address,\r
968 IN UINT32 AndData\r
969 )\r
970{\r
971 return PciWrite32 (Address, PciRead32 (Address) & AndData);\r
972}\r
973\r
974/**\r
975 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
976 value, followed a bitwise inclusive OR with another 32-bit value.\r
977\r
978 Reads the 32-bit PCI configuration register specified by Address, performs a\r
979 bitwise AND between the read result and the value specified by AndData,\r
980 performs a bitwise inclusive OR between the result of the AND operation and\r
981 the value specified by OrData, and writes the result to the 32-bit PCI\r
982 configuration register specified by Address. The value written to the PCI\r
983 configuration register is returned. This function must guarantee that all PCI\r
984 read and write operations are serialized.\r
985\r
986 If Address > 0x0FFFFFFF, then ASSERT().\r
987 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
988\r
989 @param Address Address that encodes the PCI Bus, Device, Function and\r
990 Register.\r
991 @param AndData The value to AND with the PCI configuration register.\r
992 @param OrData The value to OR with the result of the AND operation.\r
993\r
994 @return The value written back to the PCI configuration register.\r
995\r
996**/\r
997UINT32\r
998EFIAPI\r
999PciAndThenOr32 (\r
1000 IN UINTN Address,\r
1001 IN UINT32 AndData,\r
1002 IN UINT32 OrData\r
1003 )\r
1004{\r
1005 return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);\r
1006}\r
1007\r
1008/**\r
1009 Reads a bit field of a PCI configuration register.\r
1010\r
1011 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
1012 specified by the StartBit and the EndBit. The value of the bit field is\r
1013 returned.\r
1014\r
1015 If Address > 0x0FFFFFFF, then ASSERT().\r
1016 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1017 If StartBit is greater than 31, then ASSERT().\r
1018 If EndBit is greater than 31, then ASSERT().\r
1019 If EndBit is less than StartBit, then ASSERT().\r
1020\r
1021 @param Address PCI configuration register to read.\r
1022 @param StartBit The ordinal of the least significant bit in the bit field.\r
1023 Range 0..31.\r
1024 @param EndBit The ordinal of the most significant bit in the bit field.\r
1025 Range 0..31.\r
1026\r
1027 @return The value of the bit field read from the PCI configuration register.\r
1028\r
1029**/\r
1030UINT32\r
1031EFIAPI\r
1032PciBitFieldRead32 (\r
1033 IN UINTN Address,\r
1034 IN UINTN StartBit,\r
1035 IN UINTN EndBit\r
1036 )\r
1037{\r
1038 return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);\r
1039}\r
1040\r
1041/**\r
1042 Writes a bit field to a PCI configuration register.\r
1043\r
1044 Writes Value to the bit field of the PCI configuration register. The bit\r
1045 field is specified by the StartBit and the EndBit. All other bits in the\r
1046 destination PCI configuration register are preserved. The new value of the\r
1047 32-bit register is returned.\r
1048\r
1049 If Address > 0x0FFFFFFF, then ASSERT().\r
1050 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1051 If StartBit is greater than 31, then ASSERT().\r
1052 If EndBit is greater than 31, then ASSERT().\r
1053 If EndBit is less than StartBit, then ASSERT().\r
1054\r
1055 @param Address PCI configuration register to write.\r
1056 @param StartBit The ordinal of the least significant bit in the bit field.\r
1057 Range 0..31.\r
1058 @param EndBit The ordinal of the most significant bit in the bit field.\r
1059 Range 0..31.\r
1060 @param Value New value of the bit field.\r
1061\r
1062 @return The value written back to the PCI configuration register.\r
1063\r
1064**/\r
1065UINT32\r
1066EFIAPI\r
1067PciBitFieldWrite32 (\r
1068 IN UINTN Address,\r
1069 IN UINTN StartBit,\r
1070 IN UINTN EndBit,\r
1071 IN UINT32 Value\r
1072 )\r
1073{\r
1074 return PciWrite32 (\r
1075 Address,\r
1076 BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)\r
1077 );\r
1078}\r
1079\r
1080/**\r
1081 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
1082 writes the result back to the bit field in the 32-bit port.\r
1083\r
1084 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1085 bitwise inclusive OR between the read result and the value specified by\r
1086 OrData, and writes the result to the 32-bit PCI configuration register\r
1087 specified by Address. The value written to the PCI configuration register is\r
1088 returned. This function must guarantee that all PCI read and write operations\r
1089 are serialized. Extra left bits in OrData are stripped.\r
1090\r
1091 If Address > 0x0FFFFFFF, then ASSERT().\r
1092 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1093 If StartBit is greater than 31, then ASSERT().\r
1094 If EndBit is greater than 31, then ASSERT().\r
1095 If EndBit is less than StartBit, then ASSERT().\r
1096\r
1097 @param Address PCI configuration register to write.\r
1098 @param StartBit The ordinal of the least significant bit in the bit field.\r
1099 Range 0..31.\r
1100 @param EndBit The ordinal of the most significant bit in the bit field.\r
1101 Range 0..31.\r
1102 @param OrData The value to OR with the PCI configuration register.\r
1103\r
1104 @return The value written back to the PCI configuration register.\r
1105\r
1106**/\r
1107UINT32\r
1108EFIAPI\r
1109PciBitFieldOr32 (\r
1110 IN UINTN Address,\r
1111 IN UINTN StartBit,\r
1112 IN UINTN EndBit,\r
1113 IN UINT32 OrData\r
1114 )\r
1115{\r
1116 return PciWrite32 (\r
1117 Address,\r
1118 BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)\r
1119 );\r
1120}\r
1121\r
1122/**\r
1123 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1124 AND, and writes the result back to the bit field in the 32-bit register.\r
1125\r
1126 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1127 bitwise AND between the read result and the value specified by AndData, and\r
1128 writes the result to the 32-bit PCI configuration register specified by\r
1129 Address. The value written to the PCI configuration register is returned.\r
1130 This function must guarantee that all PCI read and write operations are\r
1131 serialized. Extra left bits in AndData are stripped.\r
1132\r
1133 If Address > 0x0FFFFFFF, then ASSERT().\r
1134 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1135 If StartBit is greater than 31, then ASSERT().\r
1136 If EndBit is greater than 31, then ASSERT().\r
1137 If EndBit is less than StartBit, then ASSERT().\r
1138\r
1139 @param Address PCI configuration register to write.\r
1140 @param StartBit The ordinal of the least significant bit in the bit field.\r
1141 Range 0..31.\r
1142 @param EndBit The ordinal of the most significant bit in the bit field.\r
1143 Range 0..31.\r
1144 @param AndData The value to AND with the PCI configuration register.\r
1145\r
1146 @return The value written back to the PCI configuration register.\r
1147\r
1148**/\r
1149UINT32\r
1150EFIAPI\r
1151PciBitFieldAnd32 (\r
1152 IN UINTN Address,\r
1153 IN UINTN StartBit,\r
1154 IN UINTN EndBit,\r
1155 IN UINT32 AndData\r
1156 )\r
1157{\r
1158 return PciWrite32 (\r
1159 Address,\r
1160 BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)\r
1161 );\r
1162}\r
1163\r
1164/**\r
1165 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
1166 bitwise inclusive OR, and writes the result back to the bit field in the\r
1167 32-bit port.\r
1168\r
1169 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1170 bitwise AND followed by a bitwise inclusive OR between the read result and\r
1171 the value specified by AndData, and writes the result to the 32-bit PCI\r
1172 configuration register specified by Address. The value written to the PCI\r
1173 configuration register is returned. This function must guarantee that all PCI\r
1174 read and write operations are serialized. Extra left bits in both AndData and\r
1175 OrData are stripped.\r
1176\r
1177 If Address > 0x0FFFFFFF, then ASSERT().\r
1178 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1179 If StartBit is greater than 31, then ASSERT().\r
1180 If EndBit is greater than 31, then ASSERT().\r
1181 If EndBit is less than StartBit, then ASSERT().\r
1182\r
1183 @param Address PCI configuration register to write.\r
1184 @param StartBit The ordinal of the least significant bit in the bit field.\r
1185 Range 0..31.\r
1186 @param EndBit The ordinal of the most significant bit in the bit field.\r
1187 Range 0..31.\r
1188 @param AndData The value to AND with the PCI configuration register.\r
1189 @param OrData The value to OR with the result of the AND operation.\r
1190\r
1191 @return The value written back to the PCI configuration register.\r
1192\r
1193**/\r
1194UINT32\r
1195EFIAPI\r
1196PciBitFieldAndThenOr32 (\r
1197 IN UINTN Address,\r
1198 IN UINTN StartBit,\r
1199 IN UINTN EndBit,\r
1200 IN UINT32 AndData,\r
1201 IN UINT32 OrData\r
1202 )\r
1203{\r
1204 return PciWrite32 (\r
1205 Address,\r
1206 BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)\r
1207 );\r
1208}\r
1209\r
1210/**\r
1211 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1212\r
1213 Reads the range of PCI configuration registers specified by StartAddress and\r
1214 Size into the buffer specified by Buffer. This function only allows the PCI\r
1215 configuration registers from a single PCI function to be read. Size is\r
1216 returned. When possible 32-bit PCI configuration read cycles are used to read\r
1217 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
1218 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1219 end of the range.\r
1220\r
1221 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1222 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1223 If Size > 0 and Buffer is NULL, then ASSERT().\r
1224\r
1225 @param StartAddress Starting address that encodes the PCI Bus, Device,\r
1226 Function and Register.\r
1227 @param Size Size in bytes of the transfer.\r
1228 @param Buffer Pointer to a buffer receiving the data read.\r
1229\r
1230 @return Size\r
1231\r
1232**/\r
1233UINTN\r
1234EFIAPI\r
1235PciReadBuffer (\r
1236 IN UINTN StartAddress,\r
1237 IN UINTN Size,\r
1238 OUT VOID *Buffer\r
1239 )\r
1240{\r
1241 UINTN ReturnValue;\r
1242\r
1243 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
e43e4b3e 1244 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1a3eaf06 1245\r
1246 if (Size == 0) {\r
1247 return Size;\r
1248 }\r
1249\r
1250 ASSERT (Buffer != NULL);\r
1251\r
1252 //\r
1253 // Save Size for return\r
1254 //\r
1255 ReturnValue = Size;\r
1256\r
e43e4b3e 1257 if ((StartAddress & BIT0) != 0) {\r
1a3eaf06 1258 //\r
1259 // Read a byte if StartAddress is byte aligned\r
1260 //\r
1261 *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);\r
1262 StartAddress += sizeof (UINT8);\r
1263 Size -= sizeof (UINT8);\r
1264 Buffer = (UINT8*)Buffer + 1;\r
1265 }\r
1266\r
e43e4b3e 1267 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1a3eaf06 1268 //\r
1269 // Read a word if StartAddress is word aligned\r
1270 //\r
1271 *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);\r
1272 StartAddress += sizeof (UINT16);\r
1273 Size -= sizeof (UINT16);\r
1274 Buffer = (UINT16*)Buffer + 1;\r
1275 }\r
1276\r
1277 while (Size >= sizeof (UINT32)) {\r
1278 //\r
1279 // Read as many double words as possible\r
1280 //\r
1281 *(volatile UINT32 *)Buffer = PciRead32 (StartAddress);\r
1282 StartAddress += sizeof (UINT32);\r
1283 Size -= sizeof (UINT32);\r
1284 Buffer = (UINT32*)Buffer + 1;\r
1285 }\r
1286\r
1287 if (Size >= sizeof (UINT16)) {\r
1288 //\r
1289 // Read the last remaining word if exist\r
1290 //\r
1291 *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);\r
1292 StartAddress += sizeof (UINT16);\r
1293 Size -= sizeof (UINT16);\r
1294 Buffer = (UINT16*)Buffer + 1;\r
1295 }\r
1296\r
1297 if (Size >= sizeof (UINT8)) {\r
1298 //\r
1299 // Read the last remaining byte if exist\r
1300 //\r
1301 *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);\r
1302 }\r
1303\r
1304 return ReturnValue;\r
1305}\r
1306\r
1307/**\r
1308 Copies the data in a caller supplied buffer to a specified range of PCI\r
1309 configuration space.\r
1310\r
1311 Writes the range of PCI configuration registers specified by StartAddress and\r
1312 Size from the buffer specified by Buffer. This function only allows the PCI\r
1313 configuration registers from a single PCI function to be written. Size is\r
1314 returned. When possible 32-bit PCI configuration write cycles are used to\r
1315 write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
1316 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1317 and the end of the range.\r
1318\r
1319 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1320 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1321 If Size > 0 and Buffer is NULL, then ASSERT().\r
1322\r
1323 @param StartAddress Starting address that encodes the PCI Bus, Device,\r
1324 Function and Register.\r
1325 @param Size Size in bytes of the transfer.\r
1326 @param Buffer Pointer to a buffer containing the data to write.\r
1327\r
1328 @return Size\r
1329\r
1330**/\r
1331UINTN\r
1332EFIAPI\r
1333PciWriteBuffer (\r
1334 IN UINTN StartAddress,\r
1335 IN UINTN Size,\r
1336 IN VOID *Buffer\r
1337 )\r
1338{\r
1339 UINTN ReturnValue;\r
1340\r
1341 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
e43e4b3e 1342 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1a3eaf06 1343\r
1344 if (Size == 0) {\r
1345 return 0;\r
1346 }\r
1347\r
1348 ASSERT (Buffer != NULL);\r
1349\r
1350 //\r
1351 // Save Size for return\r
1352 //\r
1353 ReturnValue = Size;\r
1354\r
e43e4b3e 1355 if ((StartAddress & BIT0) != 0) {\r
1a3eaf06 1356 //\r
1357 // Write a byte if StartAddress is byte aligned\r
1358 //\r
1359 PciWrite8 (StartAddress, *(UINT8*)Buffer);\r
1360 StartAddress += sizeof (UINT8);\r
1361 Size -= sizeof (UINT8);\r
1362 Buffer = (UINT8*)Buffer + 1;\r
1363 }\r
1364\r
e43e4b3e 1365 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1a3eaf06 1366 //\r
1367 // Write a word if StartAddress is word aligned\r
1368 //\r
1369 PciWrite16 (StartAddress, *(UINT16*)Buffer);\r
1370 StartAddress += sizeof (UINT16);\r
1371 Size -= sizeof (UINT16);\r
1372 Buffer = (UINT16*)Buffer + 1;\r
1373 }\r
1374\r
1375 while (Size >= sizeof (UINT32)) {\r
1376 //\r
1377 // Write as many double words as possible\r
1378 //\r
1379 PciWrite32 (StartAddress, *(UINT32*)Buffer);\r
1380 StartAddress += sizeof (UINT32);\r
1381 Size -= sizeof (UINT32);\r
1382 Buffer = (UINT32*)Buffer + 1;\r
1383 }\r
1384\r
1385 if (Size >= sizeof (UINT16)) {\r
1386 //\r
1387 // Write the last remaining word if exist\r
1388 //\r
1389 PciWrite16 (StartAddress, *(UINT16*)Buffer);\r
1390 StartAddress += sizeof (UINT16);\r
1391 Size -= sizeof (UINT16);\r
1392 Buffer = (UINT16*)Buffer + 1;\r
1393 }\r
1394\r
1395 if (Size >= sizeof (UINT8)) {\r
1396 //\r
1397 // Write the last remaining byte if exist\r
1398 //\r
1399 PciWrite8 (StartAddress, *(UINT8*)Buffer);\r
1400 }\r
1401\r
1402 return ReturnValue;\r
1403}\r