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