VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c@ 109091

Last change on this file since 109091 was 108794, checked in by vboxsync, 5 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette