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