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