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