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