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