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