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