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