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