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