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