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