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