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