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