]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
Spec checked
[mirror_edk2.git] / MdePkg / Library / DxeRuntimePciExpressLib / PciExpressLib.c
1 /** @file
2 Functions in this library instance make use of MMIO functions in IoLib to
3 access memory mapped PCI configuration space.
4
5 All assertions for I/O operations are handled in MMIO functions in the IoLib
6 Library.
7
8 Copyright (c) 2006 - 2008, Intel Corporation<BR>
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 **/
18
19
20 #include <PiDxe.h>
21
22 #include <Library/BaseLib.h>
23 #include <Library/PciExpressLib.h>
24 #include <Library/IoLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/DxeServicesTableLib.h>
30 #include <Library/UefiRuntimeLib.h>
31
32 ///
33 /// Define table for mapping PCI Express MMIO physical addresses to virtual addresses at OS runtime
34 ///
35 typedef struct {
36 UINTN PhysicalAddress;
37 UINTN VirtualAddress;
38 } PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE;
39
40 ///
41 /// Set Virtual Address Map Event
42 ///
43 EFI_EVENT mDxeRuntimePciExpressLibVirtualNotifyEvent = NULL;
44
45 ///
46 /// Module global that contains the base physical address of the PCI Express MMIO range
47 ///
48 UINTN mDxeRuntimePciExpressLibPciExpressBaseAddress = 0;
49
50 ///
51 /// The number of PCI devices that have been registered for runtime access
52 ///
53 UINTN mDxeRuntimePciExpressLibNumberOfRuntimeRanges = 0;
54
55 ///
56 /// The table of PCI devices that have been registered for runtime access
57 ///
58 PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE *mDxeRuntimePciExpressLibRegistrationTable = NULL;
59
60 ///
61 /// The table index of the most recent virtual address lookup
62 ///
63 UINTN mDxeRuntimePciExpressLibLastRuntimeRange = 0;
64
65
66 /**
67 Convert the physical PCI Express MMIO addresses for all registered PCI devices
68 to virtual addresses.
69
70 @param[in] Event The Event that is being processed
71 @param[in] Context Event Context
72 **/
73 VOID
74 EFIAPI
75 DxeRuntimePciExpressLibVirtualNotify (
76 IN EFI_EVENT Event,
77 IN VOID *Context
78 )
79 {
80 UINTN Index;
81
82 //
83 // If there have been no runtime registrations, then just return
84 //
85 if (mDxeRuntimePciExpressLibRegistrationTable == NULL) {
86 return;
87 }
88
89 //
90 // Convert physical addresses associated with the set of registered PCI devices to
91 // virtual addresses.
92 //
93 for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {
94 EfiConvertPointer (0, (VOID **) &(mDxeRuntimePciExpressLibRegistrationTable[Index].VirtualAddress));
95 }
96
97 //
98 // Convert table pointer that is allocated from EfiRuntimeServicesData to a virtual address.
99 //
100 EfiConvertPointer (0, (VOID **) &mDxeRuntimePciExpressLibRegistrationTable);
101 }
102
103 /**
104 The constructor function caches the PCI Express Base Address and creates a
105 Set Virtual Address Map event to convert physical address to virtual addresses.
106
107 @param ImageHandle The firmware allocated handle for the EFI image.
108 @param SystemTable A pointer to the EFI System Table.
109
110 @retval EFI_SUCCESS The constructor completed successfully.
111 @retval Other value The constructor did not complete successfully.
112
113 **/
114 EFI_STATUS
115 EFIAPI
116 DxeRuntimePciExpressLibConstructor (
117 IN EFI_HANDLE ImageHandle,
118 IN EFI_SYSTEM_TABLE *SystemTable
119 )
120 {
121 EFI_STATUS Status;
122
123 //
124 // Cache the physical address of the PCI Express MMIO range into a module global variable
125 //
126 mDxeRuntimePciExpressLibPciExpressBaseAddress = (UINTN) PcdGet64 (PcdPciExpressBaseAddress);
127
128 //
129 // Register SetVirtualAddressMap () notify function
130 //
131 Status = gBS->CreateEvent (
132 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
133 TPL_NOTIFY,
134 DxeRuntimePciExpressLibVirtualNotify,
135 NULL,
136 &mDxeRuntimePciExpressLibVirtualNotifyEvent
137 );
138 ASSERT_EFI_ERROR (Status);
139
140 return Status;
141 }
142
143 /**
144 The destructor function frees any allocated buffers and closes the Set Virtual
145 Address Map event.
146
147 @param ImageHandle The firmware allocated handle for the EFI image.
148 @param SystemTable A pointer to the EFI System Table.
149
150 @retval EFI_SUCCESS The destructor completed successfully.
151 @retval Other value The destructor did not complete successfully.
152
153 **/
154 EFI_STATUS
155 EFIAPI
156 DxeRuntimePciExpressLibDestructor (
157 IN EFI_HANDLE ImageHandle,
158 IN EFI_SYSTEM_TABLE *SystemTable
159 )
160 {
161 EFI_STATUS Status;
162
163 //
164 // If one or more PCI devices have been registered for runtime access, then
165 // free the registration table.
166 //
167 if (mDxeRuntimePciExpressLibRegistrationTable != NULL) {
168 FreePool (mDxeRuntimePciExpressLibRegistrationTable);
169 }
170
171 //
172 // Close the Set Virtual Address Map event
173 //
174 Status = gBS->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent);
175 ASSERT_EFI_ERROR (Status);
176
177 return Status;
178 }
179
180 /**
181 Gets the base address of PCI Express.
182
183 This internal functions retrieves PCI Express Base Address via a PCD entry
184 PcdPciExpressBaseAddress.
185
186 @param Address Address that encodes the PCI Bus, Device, Function and Register.
187 @return The base address of PCI Express.
188
189 **/
190 UINTN
191 GetPciExpressAddress (
192 IN UINTN Address
193 )
194 {
195 UINTN Index;
196
197 //
198 // Make sure Address is valid
199 //
200 ASSERT (((Address) & ~0xfffffff) == 0);
201
202 //
203 // Convert Address to a physical address in the MMIO PCI Express range
204 //
205 Address += mDxeRuntimePciExpressLibPciExpressBaseAddress;
206
207 //
208 // If SetVirtualAddressMap() has not been called, then just return the physical address
209 //
210 if (!EfiGoneVirtual ()) {
211 return Address;
212 }
213
214 //
215 // See if there is a physical address match at the exact same index as the last address match
216 //
217 if (mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibLastRuntimeRange].PhysicalAddress == (Address & 0x0ffff000)) {
218 //
219 // Convert the physical address to a virtual address and return the virtual address
220 //
221 return (Address & 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibLastRuntimeRange].VirtualAddress;
222 }
223
224 //
225 // Search the entire table for a phyical address match
226 //
227 for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {
228 if (mDxeRuntimePciExpressLibRegistrationTable[Index].PhysicalAddress == (Address & 0x0ffff000)) {
229 //
230 // Cache the matching index value
231 //
232 mDxeRuntimePciExpressLibLastRuntimeRange = Index;
233 //
234 // Convert the physical address to a virtual address and return the virtual address
235 //
236 return (Address & 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable[Index].VirtualAddress;
237 }
238 }
239
240 //
241 // No match was found. This is a critical error at OS runtime, so ASSERT() and force a breakpoint.
242 //
243 ASSERT (FALSE);
244 CpuBreakpoint();
245
246 //
247 // Return the physical address
248 //
249 return Address;
250 }
251
252 /**
253 Registers a PCI device so PCI configuration registers may be accessed after
254 SetVirtualAddressMap().
255
256 Registers the PCI device specified by Address so all the PCI configuration
257 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
258 is called.
259
260 If Address > 0x0FFFFFFF, then ASSERT().
261
262 @param Address Address that encodes the PCI Bus, Device, Function and
263 Register.
264
265 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
266 @retval RETURN_UNSUPPORTED An attempt was made to call this function
267 after ExitBootServices().
268 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
269 at runtime could not be mapped.
270 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
271 complete the registration.
272
273 **/
274 RETURN_STATUS
275 EFIAPI
276 PciExpressRegisterForRuntimeAccess (
277 IN UINTN Address
278 )
279 {
280 EFI_STATUS Status;
281 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
282 UINTN Index;
283 VOID *NewTable;
284
285 //
286 // Return an error if this function is called after ExitBootServices().
287 //
288 if (EfiAtRuntime ()) {
289 return RETURN_UNSUPPORTED;
290 }
291
292 //
293 // Make sure Address is valid
294 //
295 ASSERT (((Address) & ~0xfffffff) == 0);
296
297 //
298 // Convert Address to a physical address in the MMIO PCI Express range
299 // at the beginning of the PCI Configuration header for the specified
300 // PCI Bus/Dev/Func
301 //
302 Address = GetPciExpressAddress (Address & 0x0ffff000);
303
304 //
305 // See if Address has already been registerd for runtime access
306 //
307 for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {
308 if (mDxeRuntimePciExpressLibRegistrationTable[Index].PhysicalAddress == Address) {
309 return RETURN_SUCCESS;
310 }
311 }
312
313 //
314 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
315 //
316 Status = gDS->GetMemorySpaceDescriptor (Address, &Descriptor);
317 if (EFI_ERROR (Status)) {
318 return RETURN_UNSUPPORTED;
319 }
320
321 //
322 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
323 // will allocate a virtual address range for the 4KB PCI Configuration Header.
324 //
325 Status = gDS->SetMemorySpaceAttributes (Address, 0x1000, Descriptor.Attributes | EFI_MEMORY_RUNTIME);
326 if (EFI_ERROR (Status)) {
327 return RETURN_UNSUPPORTED;
328 }
329
330 //
331 // Grow the size of the registration table
332 //
333 NewTable = ReallocateRuntimePool (
334 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges + 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE),
335 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges + 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE),
336 mDxeRuntimePciExpressLibRegistrationTable
337 );
338 if (NewTable == NULL) {
339 return RETURN_OUT_OF_RESOURCES;
340 }
341 mDxeRuntimePciExpressLibRegistrationTable = NewTable;
342 mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibNumberOfRuntimeRanges].PhysicalAddress = Address;
343 mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibNumberOfRuntimeRanges].VirtualAddress = Address;
344 mDxeRuntimePciExpressLibNumberOfRuntimeRanges++;
345
346 return RETURN_SUCCESS;
347 }
348
349
350 /**
351 Reads an 8-bit PCI configuration register.
352
353 Reads and returns the 8-bit PCI configuration register specified by Address.
354 This function must guarantee that all PCI read and write operations are
355 serialized.
356
357 If Address > 0x0FFFFFFF, then ASSERT().
358
359 @param Address Address that encodes the PCI Bus, Device, Function and
360 Register.
361
362 @return The read value from the PCI configuration register.
363
364 **/
365 UINT8
366 EFIAPI
367 PciExpressRead8 (
368 IN UINTN Address
369 )
370 {
371 return MmioRead8 (GetPciExpressAddress (Address));
372 }
373
374 /**
375 Writes an 8-bit PCI configuration register.
376
377 Writes the 8-bit PCI configuration register specified by Address with the
378 value specified by Value. Value is returned. This function must guarantee
379 that all PCI read and write operations are serialized.
380
381 If Address > 0x0FFFFFFF, then ASSERT().
382
383 @param Address Address that encodes the PCI Bus, Device, Function and
384 Register.
385 @param Value The value to write.
386
387 @return The value written to the PCI configuration register.
388
389 **/
390 UINT8
391 EFIAPI
392 PciExpressWrite8 (
393 IN UINTN Address,
394 IN UINT8 Value
395 )
396 {
397 return MmioWrite8 (GetPciExpressAddress (Address), Value);
398 }
399
400 /**
401 Performs a bitwise OR of an 8-bit PCI configuration register with
402 an 8-bit value.
403
404 Reads the 8-bit PCI configuration register specified by Address, performs a
405 bitwise OR between the read result and the value specified by
406 OrData, and writes the result to the 8-bit PCI configuration register
407 specified by Address. The value written to the PCI configuration register is
408 returned. This function must guarantee that all PCI read and write operations
409 are serialized.
410
411 If Address > 0x0FFFFFFF, then ASSERT().
412
413 @param Address Address that encodes the PCI Bus, Device, Function and
414 Register.
415 @param OrData The value to OR with the PCI configuration register.
416
417 @return The value written back to the PCI configuration register.
418
419 **/
420 UINT8
421 EFIAPI
422 PciExpressOr8 (
423 IN UINTN Address,
424 IN UINT8 OrData
425 )
426 {
427 return MmioOr8 (GetPciExpressAddress (Address), OrData);
428 }
429
430 /**
431 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
432 value.
433
434 Reads the 8-bit PCI configuration register specified by Address, performs a
435 bitwise AND between the read result and the value specified by AndData, and
436 writes the result to the 8-bit PCI configuration register specified by
437 Address. The value written to the PCI configuration register is returned.
438 This function must guarantee that all PCI read and write operations are
439 serialized.
440
441 If Address > 0x0FFFFFFF, then ASSERT().
442
443 @param Address Address that encodes the PCI Bus, Device, Function and
444 Register.
445 @param AndData The value to AND with the PCI configuration register.
446
447 @return The value written back to the PCI configuration register.
448
449 **/
450 UINT8
451 EFIAPI
452 PciExpressAnd8 (
453 IN UINTN Address,
454 IN UINT8 AndData
455 )
456 {
457 return MmioAnd8 (GetPciExpressAddress (Address), AndData);
458 }
459
460 /**
461 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
462 value, followed a bitwise OR with another 8-bit value.
463
464 Reads the 8-bit PCI configuration register specified by Address, performs a
465 bitwise AND between the read result and the value specified by AndData,
466 performs a bitwise OR between the result of the AND operation and
467 the value specified by OrData, and writes the result to the 8-bit PCI
468 configuration register specified by Address. The value written to the PCI
469 configuration register is returned. This function must guarantee that all PCI
470 read and write operations are serialized.
471
472 If Address > 0x0FFFFFFF, then ASSERT().
473
474 @param Address Address that encodes the PCI Bus, Device, Function and
475 Register.
476 @param AndData The value to AND with the PCI configuration register.
477 @param OrData The value to OR with the result of the AND operation.
478
479 @return The value written back to the PCI configuration register.
480
481 **/
482 UINT8
483 EFIAPI
484 PciExpressAndThenOr8 (
485 IN UINTN Address,
486 IN UINT8 AndData,
487 IN UINT8 OrData
488 )
489 {
490 return MmioAndThenOr8 (
491 GetPciExpressAddress (Address),
492 AndData,
493 OrData
494 );
495 }
496
497 /**
498 Reads a bit field of a PCI configuration register.
499
500 Reads the bit field in an 8-bit PCI configuration register. The bit field is
501 specified by the StartBit and the EndBit. The value of the bit field is
502 returned.
503
504 If Address > 0x0FFFFFFF, then ASSERT().
505 If StartBit is greater than 7, then ASSERT().
506 If EndBit is greater than 7, then ASSERT().
507 If EndBit is less than StartBit, then ASSERT().
508
509 @param Address PCI configuration register to read.
510 @param StartBit The ordinal of the least significant bit in the bit field.
511 Range 0..7.
512 @param EndBit The ordinal of the most significant bit in the bit field.
513 Range 0..7.
514
515 @return The value of the bit field read from the PCI configuration register.
516
517 **/
518 UINT8
519 EFIAPI
520 PciExpressBitFieldRead8 (
521 IN UINTN Address,
522 IN UINTN StartBit,
523 IN UINTN EndBit
524 )
525 {
526 return MmioBitFieldRead8 (
527 GetPciExpressAddress (Address),
528 StartBit,
529 EndBit
530 );
531 }
532
533 /**
534 Writes a bit field to a PCI configuration register.
535
536 Writes Value to the bit field of the PCI configuration register. The bit
537 field is specified by the StartBit and the EndBit. All other bits in the
538 destination PCI configuration register are preserved. The new value of the
539 8-bit register is returned.
540
541 If Address > 0x0FFFFFFF, then ASSERT().
542 If StartBit is greater than 7, then ASSERT().
543 If EndBit is greater than 7, then ASSERT().
544 If EndBit is less than StartBit, then ASSERT().
545
546 @param Address PCI configuration register to write.
547 @param StartBit The ordinal of the least significant bit in the bit field.
548 Range 0..7.
549 @param EndBit The ordinal of the most significant bit in the bit field.
550 Range 0..7.
551 @param Value New value of the bit field.
552
553 @return The value written back to the PCI configuration register.
554
555 **/
556 UINT8
557 EFIAPI
558 PciExpressBitFieldWrite8 (
559 IN UINTN Address,
560 IN UINTN StartBit,
561 IN UINTN EndBit,
562 IN UINT8 Value
563 )
564 {
565 return MmioBitFieldWrite8 (
566 GetPciExpressAddress (Address),
567 StartBit,
568 EndBit,
569 Value
570 );
571 }
572
573 /**
574 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
575 writes the result back to the bit field in the 8-bit port.
576
577 Reads the 8-bit PCI configuration register specified by Address, performs a
578 bitwise OR between the read result and the value specified by
579 OrData, and writes the result to the 8-bit PCI configuration register
580 specified by Address. The value written to the PCI configuration register is
581 returned. This function must guarantee that all PCI read and write operations
582 are serialized. Extra left bits in OrData are stripped.
583
584 If Address > 0x0FFFFFFF, then ASSERT().
585 If StartBit is greater than 7, then ASSERT().
586 If EndBit is greater than 7, then ASSERT().
587 If EndBit is less than StartBit, then ASSERT().
588
589 @param Address PCI configuration register to write.
590 @param StartBit The ordinal of the least significant bit in the bit field.
591 Range 0..7.
592 @param EndBit The ordinal of the most significant bit in the bit field.
593 Range 0..7.
594 @param OrData The value to OR with the PCI configuration register.
595
596 @return The value written back to the PCI configuration register.
597
598 **/
599 UINT8
600 EFIAPI
601 PciExpressBitFieldOr8 (
602 IN UINTN Address,
603 IN UINTN StartBit,
604 IN UINTN EndBit,
605 IN UINT8 OrData
606 )
607 {
608 return MmioBitFieldOr8 (
609 GetPciExpressAddress (Address),
610 StartBit,
611 EndBit,
612 OrData
613 );
614 }
615
616 /**
617 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
618 AND, and writes the result back to the bit field in the 8-bit register.
619
620 Reads the 8-bit PCI configuration register specified by Address, performs a
621 bitwise AND between the read result and the value specified by AndData, and
622 writes the result to the 8-bit PCI configuration register specified by
623 Address. The value written to the PCI configuration register is returned.
624 This function must guarantee that all PCI read and write operations are
625 serialized. Extra left bits in AndData are stripped.
626
627 If Address > 0x0FFFFFFF, then ASSERT().
628 If StartBit is greater than 7, then ASSERT().
629 If EndBit is greater than 7, then ASSERT().
630 If EndBit is less than StartBit, then ASSERT().
631
632 @param Address PCI configuration register to write.
633 @param StartBit The ordinal of the least significant bit in the bit field.
634 Range 0..7.
635 @param EndBit The ordinal of the most significant bit in the bit field.
636 Range 0..7.
637 @param AndData The value to AND with the PCI configuration register.
638
639 @return The value written back to the PCI configuration register.
640
641 **/
642 UINT8
643 EFIAPI
644 PciExpressBitFieldAnd8 (
645 IN UINTN Address,
646 IN UINTN StartBit,
647 IN UINTN EndBit,
648 IN UINT8 AndData
649 )
650 {
651 return MmioBitFieldAnd8 (
652 GetPciExpressAddress (Address),
653 StartBit,
654 EndBit,
655 AndData
656 );
657 }
658
659 /**
660 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
661 bitwise OR, and writes the result back to the bit field in the
662 8-bit port.
663
664 Reads the 8-bit PCI configuration register specified by Address, performs a
665 bitwise AND followed by a bitwise OR between the read result and
666 the value specified by AndData, and writes the result to the 8-bit PCI
667 configuration register specified by Address. The value written to the PCI
668 configuration register is returned. This function must guarantee that all PCI
669 read and write operations are serialized. Extra left bits in both AndData and
670 OrData are stripped.
671
672 If Address > 0x0FFFFFFF, then ASSERT().
673 If StartBit is greater than 7, then ASSERT().
674 If EndBit is greater than 7, then ASSERT().
675 If EndBit is less than StartBit, then ASSERT().
676
677 @param Address PCI configuration register to write.
678 @param StartBit The ordinal of the least significant bit in the bit field.
679 Range 0..7.
680 @param EndBit The ordinal of the most significant bit in the bit field.
681 Range 0..7.
682 @param AndData The value to AND with the PCI configuration register.
683 @param OrData The value to OR with the result of the AND operation.
684
685 @return The value written back to the PCI configuration register.
686
687 **/
688 UINT8
689 EFIAPI
690 PciExpressBitFieldAndThenOr8 (
691 IN UINTN Address,
692 IN UINTN StartBit,
693 IN UINTN EndBit,
694 IN UINT8 AndData,
695 IN UINT8 OrData
696 )
697 {
698 return MmioBitFieldAndThenOr8 (
699 GetPciExpressAddress (Address),
700 StartBit,
701 EndBit,
702 AndData,
703 OrData
704 );
705 }
706
707 /**
708 Reads a 16-bit PCI configuration register.
709
710 Reads and returns the 16-bit PCI configuration register specified by Address.
711 This function must guarantee that all PCI read and write operations are
712 serialized.
713
714 If Address > 0x0FFFFFFF, then ASSERT().
715 If Address is not aligned on a 16-bit boundary, then ASSERT().
716
717 @param Address Address that encodes the PCI Bus, Device, Function and
718 Register.
719
720 @return The read value from the PCI configuration register.
721
722 **/
723 UINT16
724 EFIAPI
725 PciExpressRead16 (
726 IN UINTN Address
727 )
728 {
729 return MmioRead16 (GetPciExpressAddress (Address));
730 }
731
732 /**
733 Writes a 16-bit PCI configuration register.
734
735 Writes the 16-bit PCI configuration register specified by Address with the
736 value specified by Value. Value is returned. This function must guarantee
737 that all PCI read and write operations are serialized.
738
739 If Address > 0x0FFFFFFF, then ASSERT().
740 If Address is not aligned on a 16-bit boundary, then ASSERT().
741
742 @param Address Address that encodes the PCI Bus, Device, Function and
743 Register.
744 @param Value The value to write.
745
746 @return The value written to the PCI configuration register.
747
748 **/
749 UINT16
750 EFIAPI
751 PciExpressWrite16 (
752 IN UINTN Address,
753 IN UINT16 Value
754 )
755 {
756 return MmioWrite16 (GetPciExpressAddress (Address), Value);
757 }
758
759 /**
760 Performs a bitwise OR of a 16-bit PCI configuration register with
761 a 16-bit value.
762
763 Reads the 16-bit PCI configuration register specified by Address, performs a
764 bitwise OR between the read result and the value specified by
765 OrData, and writes the result to the 16-bit PCI configuration register
766 specified by Address. The value written to the PCI configuration register is
767 returned. This function must guarantee that all PCI read and write operations
768 are serialized.
769
770 If Address > 0x0FFFFFFF, then ASSERT().
771 If Address is not aligned on a 16-bit boundary, then ASSERT().
772
773 @param Address Address that encodes the PCI Bus, Device, Function and
774 Register.
775 @param OrData The value to OR with the PCI configuration register.
776
777 @return The value written back to the PCI configuration register.
778
779 **/
780 UINT16
781 EFIAPI
782 PciExpressOr16 (
783 IN UINTN Address,
784 IN UINT16 OrData
785 )
786 {
787 return MmioOr16 (GetPciExpressAddress (Address), OrData);
788 }
789
790 /**
791 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
792 value.
793
794 Reads the 16-bit PCI configuration register specified by Address, performs a
795 bitwise AND between the read result and the value specified by AndData, and
796 writes the result to the 16-bit PCI configuration register specified by
797 Address. The value written to the PCI configuration register is returned.
798 This function must guarantee that all PCI read and write operations are
799 serialized.
800
801 If Address > 0x0FFFFFFF, then ASSERT().
802 If Address is not aligned on a 16-bit boundary, then ASSERT().
803
804 @param Address Address that encodes the PCI Bus, Device, Function and
805 Register.
806 @param AndData The value to AND with the PCI configuration register.
807
808 @return The value written back to the PCI configuration register.
809
810 **/
811 UINT16
812 EFIAPI
813 PciExpressAnd16 (
814 IN UINTN Address,
815 IN UINT16 AndData
816 )
817 {
818 return MmioAnd16 (GetPciExpressAddress (Address), AndData);
819 }
820
821 /**
822 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
823 value, followed a bitwise OR with another 16-bit value.
824
825 Reads the 16-bit PCI configuration register specified by Address, performs a
826 bitwise AND between the read result and the value specified by AndData,
827 performs a bitwise OR between the result of the AND operation and
828 the value specified by OrData, and writes the result to the 16-bit PCI
829 configuration register specified by Address. The value written to the PCI
830 configuration register is returned. This function must guarantee that all PCI
831 read and write operations are serialized.
832
833 If Address > 0x0FFFFFFF, then ASSERT().
834 If Address is not aligned on a 16-bit boundary, then ASSERT().
835
836 @param Address Address that encodes the PCI Bus, Device, Function and
837 Register.
838 @param AndData The value to AND with the PCI configuration register.
839 @param OrData The value to OR with the result of the AND operation.
840
841 @return The value written back to the PCI configuration register.
842
843 **/
844 UINT16
845 EFIAPI
846 PciExpressAndThenOr16 (
847 IN UINTN Address,
848 IN UINT16 AndData,
849 IN UINT16 OrData
850 )
851 {
852 return MmioAndThenOr16 (
853 GetPciExpressAddress (Address),
854 AndData,
855 OrData
856 );
857 }
858
859 /**
860 Reads a bit field of a PCI configuration register.
861
862 Reads the bit field in a 16-bit PCI configuration register. The bit field is
863 specified by the StartBit and the EndBit. The value of the bit field is
864 returned.
865
866 If Address > 0x0FFFFFFF, then ASSERT().
867 If Address is not aligned on a 16-bit boundary, then ASSERT().
868 If StartBit is greater than 15, then ASSERT().
869 If EndBit is greater than 15, then ASSERT().
870 If EndBit is less than StartBit, then ASSERT().
871
872 @param Address PCI configuration register to read.
873 @param StartBit The ordinal of the least significant bit in the bit field.
874 Range 0..15.
875 @param EndBit The ordinal of the most significant bit in the bit field.
876 Range 0..15.
877
878 @return The value of the bit field read from the PCI configuration register.
879
880 **/
881 UINT16
882 EFIAPI
883 PciExpressBitFieldRead16 (
884 IN UINTN Address,
885 IN UINTN StartBit,
886 IN UINTN EndBit
887 )
888 {
889 return MmioBitFieldRead16 (
890 GetPciExpressAddress (Address),
891 StartBit,
892 EndBit
893 );
894 }
895
896 /**
897 Writes a bit field to a PCI configuration register.
898
899 Writes Value to the bit field of the PCI configuration register. The bit
900 field is specified by the StartBit and the EndBit. All other bits in the
901 destination PCI configuration register are preserved. The new value of the
902 16-bit register is returned.
903
904 If Address > 0x0FFFFFFF, then ASSERT().
905 If Address is not aligned on a 16-bit boundary, then ASSERT().
906 If StartBit is greater than 15, then ASSERT().
907 If EndBit is greater than 15, then ASSERT().
908 If EndBit is less than StartBit, then ASSERT().
909
910 @param Address PCI configuration register to write.
911 @param StartBit The ordinal of the least significant bit in the bit field.
912 Range 0..15.
913 @param EndBit The ordinal of the most significant bit in the bit field.
914 Range 0..15.
915 @param Value New value of the bit field.
916
917 @return The value written back to the PCI configuration register.
918
919 **/
920 UINT16
921 EFIAPI
922 PciExpressBitFieldWrite16 (
923 IN UINTN Address,
924 IN UINTN StartBit,
925 IN UINTN EndBit,
926 IN UINT16 Value
927 )
928 {
929 return MmioBitFieldWrite16 (
930 GetPciExpressAddress (Address),
931 StartBit,
932 EndBit,
933 Value
934 );
935 }
936
937 /**
938 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
939 writes the result back to the bit field in the 16-bit port.
940
941 Reads the 16-bit PCI configuration register specified by Address, performs a
942 bitwise OR between the read result and the value specified by
943 OrData, and writes the result to the 16-bit PCI configuration register
944 specified by Address. The value written to the PCI configuration register is
945 returned. This function must guarantee that all PCI read and write operations
946 are serialized. Extra left bits in OrData are stripped.
947
948 If Address > 0x0FFFFFFF, then ASSERT().
949 If Address is not aligned on a 16-bit boundary, then ASSERT().
950 If StartBit is greater than 15, then ASSERT().
951 If EndBit is greater than 15, then ASSERT().
952 If EndBit is less than StartBit, then ASSERT().
953
954 @param Address PCI configuration register to write.
955 @param StartBit The ordinal of the least significant bit in the bit field.
956 Range 0..15.
957 @param EndBit The ordinal of the most significant bit in the bit field.
958 Range 0..15.
959 @param OrData The value to OR with the PCI configuration register.
960
961 @return The value written back to the PCI configuration register.
962
963 **/
964 UINT16
965 EFIAPI
966 PciExpressBitFieldOr16 (
967 IN UINTN Address,
968 IN UINTN StartBit,
969 IN UINTN EndBit,
970 IN UINT16 OrData
971 )
972 {
973 return MmioBitFieldOr16 (
974 GetPciExpressAddress (Address),
975 StartBit,
976 EndBit,
977 OrData
978 );
979 }
980
981 /**
982 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
983 AND, and writes the result back to the bit field in the 16-bit register.
984
985 Reads the 16-bit PCI configuration register specified by Address, performs a
986 bitwise AND between the read result and the value specified by AndData, and
987 writes the result to the 16-bit PCI configuration register specified by
988 Address. The value written to the PCI configuration register is returned.
989 This function must guarantee that all PCI read and write operations are
990 serialized. Extra left bits in AndData are stripped.
991
992 If Address > 0x0FFFFFFF, then ASSERT().
993 If Address is not aligned on a 16-bit boundary, then ASSERT().
994 If StartBit is greater than 15, then ASSERT().
995 If EndBit is greater than 15, then ASSERT().
996 If EndBit is less than StartBit, then ASSERT().
997
998 @param Address PCI configuration register to write.
999 @param StartBit The ordinal of the least significant bit in the bit field.
1000 Range 0..15.
1001 @param EndBit The ordinal of the most significant bit in the bit field.
1002 Range 0..15.
1003 @param AndData The value to AND with the PCI configuration register.
1004
1005 @return The value written back to the PCI configuration register.
1006
1007 **/
1008 UINT16
1009 EFIAPI
1010 PciExpressBitFieldAnd16 (
1011 IN UINTN Address,
1012 IN UINTN StartBit,
1013 IN UINTN EndBit,
1014 IN UINT16 AndData
1015 )
1016 {
1017 return MmioBitFieldAnd16 (
1018 GetPciExpressAddress (Address),
1019 StartBit,
1020 EndBit,
1021 AndData
1022 );
1023 }
1024
1025 /**
1026 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1027 bitwise OR, and writes the result back to the bit field in the
1028 16-bit port.
1029
1030 Reads the 16-bit PCI configuration register specified by Address, performs a
1031 bitwise AND followed by a bitwise OR between the read result and
1032 the value specified by AndData, and writes the result to the 16-bit PCI
1033 configuration register specified by Address. The value written to the PCI
1034 configuration register is returned. This function must guarantee that all PCI
1035 read and write operations are serialized. Extra left bits in both AndData and
1036 OrData are stripped.
1037
1038 If Address > 0x0FFFFFFF, then ASSERT().
1039 If Address is not aligned on a 16-bit boundary, then ASSERT().
1040 If StartBit is greater than 15, then ASSERT().
1041 If EndBit is greater than 15, then ASSERT().
1042 If EndBit is less than StartBit, then ASSERT().
1043
1044 @param Address PCI configuration register to write.
1045 @param StartBit The ordinal of the least significant bit in the bit field.
1046 Range 0..15.
1047 @param EndBit The ordinal of the most significant bit in the bit field.
1048 Range 0..15.
1049 @param AndData The value to AND with the PCI configuration register.
1050 @param OrData The value to OR with the result of the AND operation.
1051
1052 @return The value written back to the PCI configuration register.
1053
1054 **/
1055 UINT16
1056 EFIAPI
1057 PciExpressBitFieldAndThenOr16 (
1058 IN UINTN Address,
1059 IN UINTN StartBit,
1060 IN UINTN EndBit,
1061 IN UINT16 AndData,
1062 IN UINT16 OrData
1063 )
1064 {
1065 return MmioBitFieldAndThenOr16 (
1066 GetPciExpressAddress (Address),
1067 StartBit,
1068 EndBit,
1069 AndData,
1070 OrData
1071 );
1072 }
1073
1074 /**
1075 Reads a 32-bit PCI configuration register.
1076
1077 Reads and returns the 32-bit PCI configuration register specified by Address.
1078 This function must guarantee that all PCI read and write operations are
1079 serialized.
1080
1081 If Address > 0x0FFFFFFF, then ASSERT().
1082 If Address is not aligned on a 32-bit boundary, then ASSERT().
1083
1084 @param Address Address that encodes the PCI Bus, Device, Function and
1085 Register.
1086
1087 @return The read value from the PCI configuration register.
1088
1089 **/
1090 UINT32
1091 EFIAPI
1092 PciExpressRead32 (
1093 IN UINTN Address
1094 )
1095 {
1096 return MmioRead32 (GetPciExpressAddress (Address));
1097 }
1098
1099 /**
1100 Writes a 32-bit PCI configuration register.
1101
1102 Writes the 32-bit PCI configuration register specified by Address with the
1103 value specified by Value. Value is returned. This function must guarantee
1104 that all PCI read and write operations are serialized.
1105
1106 If Address > 0x0FFFFFFF, then ASSERT().
1107 If Address is not aligned on a 32-bit boundary, then ASSERT().
1108
1109 @param Address Address that encodes the PCI Bus, Device, Function and
1110 Register.
1111 @param Value The value to write.
1112
1113 @return The value written to the PCI configuration register.
1114
1115 **/
1116 UINT32
1117 EFIAPI
1118 PciExpressWrite32 (
1119 IN UINTN Address,
1120 IN UINT32 Value
1121 )
1122 {
1123 return MmioWrite32 (GetPciExpressAddress (Address), Value);
1124 }
1125
1126 /**
1127 Performs a bitwise OR of a 32-bit PCI configuration register with
1128 a 32-bit value.
1129
1130 Reads the 32-bit PCI configuration register specified by Address, performs a
1131 bitwise OR between the read result and the value specified by
1132 OrData, and writes the result to the 32-bit PCI configuration register
1133 specified by Address. The value written to the PCI configuration register is
1134 returned. This function must guarantee that all PCI read and write operations
1135 are serialized.
1136
1137 If Address > 0x0FFFFFFF, then ASSERT().
1138 If Address is not aligned on a 32-bit boundary, then ASSERT().
1139
1140 @param Address Address that encodes the PCI Bus, Device, Function and
1141 Register.
1142 @param OrData The value to OR with the PCI configuration register.
1143
1144 @return The value written back to the PCI configuration register.
1145
1146 **/
1147 UINT32
1148 EFIAPI
1149 PciExpressOr32 (
1150 IN UINTN Address,
1151 IN UINT32 OrData
1152 )
1153 {
1154 return MmioOr32 (GetPciExpressAddress (Address), OrData);
1155 }
1156
1157 /**
1158 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1159 value.
1160
1161 Reads the 32-bit PCI configuration register specified by Address, performs a
1162 bitwise AND between the read result and the value specified by AndData, and
1163 writes the result to the 32-bit PCI configuration register specified by
1164 Address. The value written to the PCI configuration register is returned.
1165 This function must guarantee that all PCI read and write operations are
1166 serialized.
1167
1168 If Address > 0x0FFFFFFF, then ASSERT().
1169 If Address is not aligned on a 32-bit boundary, then ASSERT().
1170
1171 @param Address Address that encodes the PCI Bus, Device, Function and
1172 Register.
1173 @param AndData The value to AND with the PCI configuration register.
1174
1175 @return The value written back to the PCI configuration register.
1176
1177 **/
1178 UINT32
1179 EFIAPI
1180 PciExpressAnd32 (
1181 IN UINTN Address,
1182 IN UINT32 AndData
1183 )
1184 {
1185 return MmioAnd32 (GetPciExpressAddress (Address), AndData);
1186 }
1187
1188 /**
1189 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1190 value, followed a bitwise OR with another 32-bit value.
1191
1192 Reads the 32-bit PCI configuration register specified by Address, performs a
1193 bitwise AND between the read result and the value specified by AndData,
1194 performs a bitwise OR between the result of the AND operation and
1195 the value specified by OrData, and writes the result to the 32-bit PCI
1196 configuration register specified by Address. The value written to the PCI
1197 configuration register is returned. This function must guarantee that all PCI
1198 read and write operations are serialized.
1199
1200 If Address > 0x0FFFFFFF, then ASSERT().
1201 If Address is not aligned on a 32-bit boundary, then ASSERT().
1202
1203 @param Address Address that encodes the PCI Bus, Device, Function and
1204 Register.
1205 @param AndData The value to AND with the PCI configuration register.
1206 @param OrData The value to OR with the result of the AND operation.
1207
1208 @return The value written back to the PCI configuration register.
1209
1210 **/
1211 UINT32
1212 EFIAPI
1213 PciExpressAndThenOr32 (
1214 IN UINTN Address,
1215 IN UINT32 AndData,
1216 IN UINT32 OrData
1217 )
1218 {
1219 return MmioAndThenOr32 (
1220 GetPciExpressAddress (Address),
1221 AndData,
1222 OrData
1223 );
1224 }
1225
1226 /**
1227 Reads a bit field of a PCI configuration register.
1228
1229 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1230 specified by the StartBit and the EndBit. The value of the bit field is
1231 returned.
1232
1233 If Address > 0x0FFFFFFF, then ASSERT().
1234 If Address is not aligned on a 32-bit boundary, then ASSERT().
1235 If StartBit is greater than 31, then ASSERT().
1236 If EndBit is greater than 31, then ASSERT().
1237 If EndBit is less than StartBit, then ASSERT().
1238
1239 @param Address PCI configuration register to read.
1240 @param StartBit The ordinal of the least significant bit in the bit field.
1241 Range 0..31.
1242 @param EndBit The ordinal of the most significant bit in the bit field.
1243 Range 0..31.
1244
1245 @return The value of the bit field read from the PCI configuration register.
1246
1247 **/
1248 UINT32
1249 EFIAPI
1250 PciExpressBitFieldRead32 (
1251 IN UINTN Address,
1252 IN UINTN StartBit,
1253 IN UINTN EndBit
1254 )
1255 {
1256 return MmioBitFieldRead32 (
1257 GetPciExpressAddress (Address),
1258 StartBit,
1259 EndBit
1260 );
1261 }
1262
1263 /**
1264 Writes a bit field to a PCI configuration register.
1265
1266 Writes Value to the bit field of the PCI configuration register. The bit
1267 field is specified by the StartBit and the EndBit. All other bits in the
1268 destination PCI configuration register are preserved. The new value of the
1269 32-bit register is returned.
1270
1271 If Address > 0x0FFFFFFF, then ASSERT().
1272 If Address is not aligned on a 32-bit boundary, then ASSERT().
1273 If StartBit is greater than 31, then ASSERT().
1274 If EndBit is greater than 31, then ASSERT().
1275 If EndBit is less than StartBit, then ASSERT().
1276
1277 @param Address PCI configuration register to write.
1278 @param StartBit The ordinal of the least significant bit in the bit field.
1279 Range 0..31.
1280 @param EndBit The ordinal of the most significant bit in the bit field.
1281 Range 0..31.
1282 @param Value New value of the bit field.
1283
1284 @return The value written back to the PCI configuration register.
1285
1286 **/
1287 UINT32
1288 EFIAPI
1289 PciExpressBitFieldWrite32 (
1290 IN UINTN Address,
1291 IN UINTN StartBit,
1292 IN UINTN EndBit,
1293 IN UINT32 Value
1294 )
1295 {
1296 return MmioBitFieldWrite32 (
1297 GetPciExpressAddress (Address),
1298 StartBit,
1299 EndBit,
1300 Value
1301 );
1302 }
1303
1304 /**
1305 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1306 writes the result back to the bit field in the 32-bit port.
1307
1308 Reads the 32-bit PCI configuration register specified by Address, performs a
1309 bitwise OR between the read result and the value specified by
1310 OrData, and writes the result to the 32-bit PCI configuration register
1311 specified by Address. The value written to the PCI configuration register is
1312 returned. This function must guarantee that all PCI read and write operations
1313 are serialized. Extra left bits in OrData are stripped.
1314
1315 If Address > 0x0FFFFFFF, then ASSERT().
1316 If Address is not aligned on a 32-bit boundary, then ASSERT().
1317 If StartBit is greater than 31, then ASSERT().
1318 If EndBit is greater than 31, then ASSERT().
1319 If EndBit is less than StartBit, then ASSERT().
1320
1321 @param Address PCI configuration register to write.
1322 @param StartBit The ordinal of the least significant bit in the bit field.
1323 Range 0..31.
1324 @param EndBit The ordinal of the most significant bit in the bit field.
1325 Range 0..31.
1326 @param OrData The value to OR with the PCI configuration register.
1327
1328 @return The value written back to the PCI configuration register.
1329
1330 **/
1331 UINT32
1332 EFIAPI
1333 PciExpressBitFieldOr32 (
1334 IN UINTN Address,
1335 IN UINTN StartBit,
1336 IN UINTN EndBit,
1337 IN UINT32 OrData
1338 )
1339 {
1340 return MmioBitFieldOr32 (
1341 GetPciExpressAddress (Address),
1342 StartBit,
1343 EndBit,
1344 OrData
1345 );
1346 }
1347
1348 /**
1349 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1350 AND, and writes the result back to the bit field in the 32-bit register.
1351
1352 Reads the 32-bit PCI configuration register specified by Address, performs a
1353 bitwise AND between the read result and the value specified by AndData, and
1354 writes the result to the 32-bit PCI configuration register specified by
1355 Address. The value written to the PCI configuration register is returned.
1356 This function must guarantee that all PCI read and write operations are
1357 serialized. Extra left bits in AndData are stripped.
1358
1359 If Address > 0x0FFFFFFF, then ASSERT().
1360 If Address is not aligned on a 32-bit boundary, then ASSERT().
1361 If StartBit is greater than 31, then ASSERT().
1362 If EndBit is greater than 31, then ASSERT().
1363 If EndBit is less than StartBit, then ASSERT().
1364
1365 @param Address PCI configuration register to write.
1366 @param StartBit The ordinal of the least significant bit in the bit field.
1367 Range 0..31.
1368 @param EndBit The ordinal of the most significant bit in the bit field.
1369 Range 0..31.
1370 @param AndData The value to AND with the PCI configuration register.
1371
1372 @return The value written back to the PCI configuration register.
1373
1374 **/
1375 UINT32
1376 EFIAPI
1377 PciExpressBitFieldAnd32 (
1378 IN UINTN Address,
1379 IN UINTN StartBit,
1380 IN UINTN EndBit,
1381 IN UINT32 AndData
1382 )
1383 {
1384 return MmioBitFieldAnd32 (
1385 GetPciExpressAddress (Address),
1386 StartBit,
1387 EndBit,
1388 AndData
1389 );
1390 }
1391
1392 /**
1393 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1394 bitwise OR, and writes the result back to the bit field in the
1395 32-bit port.
1396
1397 Reads the 32-bit PCI configuration register specified by Address, performs a
1398 bitwise AND followed by a bitwise OR between the read result and
1399 the value specified by AndData, and writes the result to the 32-bit PCI
1400 configuration register specified by Address. The value written to the PCI
1401 configuration register is returned. This function must guarantee that all PCI
1402 read and write operations are serialized. Extra left bits in both AndData and
1403 OrData are stripped.
1404
1405 If Address > 0x0FFFFFFF, then ASSERT().
1406 If Address is not aligned on a 32-bit boundary, then ASSERT().
1407 If StartBit is greater than 31, then ASSERT().
1408 If EndBit is greater than 31, then ASSERT().
1409 If EndBit is less than StartBit, then ASSERT().
1410
1411 @param Address PCI configuration register to write.
1412 @param StartBit The ordinal of the least significant bit in the bit field.
1413 Range 0..31.
1414 @param EndBit The ordinal of the most significant bit in the bit field.
1415 Range 0..31.
1416 @param AndData The value to AND with the PCI configuration register.
1417 @param OrData The value to OR with the result of the AND operation.
1418
1419 @return The value written back to the PCI configuration register.
1420
1421 **/
1422 UINT32
1423 EFIAPI
1424 PciExpressBitFieldAndThenOr32 (
1425 IN UINTN Address,
1426 IN UINTN StartBit,
1427 IN UINTN EndBit,
1428 IN UINT32 AndData,
1429 IN UINT32 OrData
1430 )
1431 {
1432 return MmioBitFieldAndThenOr32 (
1433 GetPciExpressAddress (Address),
1434 StartBit,
1435 EndBit,
1436 AndData,
1437 OrData
1438 );
1439 }
1440
1441 /**
1442 Reads a range of PCI configuration registers into a caller supplied buffer.
1443
1444 Reads the range of PCI configuration registers specified by StartAddress and
1445 Size into the buffer specified by Buffer. This function only allows the PCI
1446 configuration registers from a single PCI function to be read. Size is
1447 returned. When possible 32-bit PCI configuration read cycles are used to read
1448 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1449 and 16-bit PCI configuration read cycles may be used at the beginning and the
1450 end of the range.
1451
1452 If StartAddress > 0x0FFFFFFF, then ASSERT().
1453 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1454 If Size > 0 and Buffer is NULL, then ASSERT().
1455
1456 @param StartAddress Starting address that encodes the PCI Bus, Device,
1457 Function and Register.
1458 @param Size Size in bytes of the transfer.
1459 @param Buffer Pointer to a buffer receiving the data read.
1460
1461 @return Size read data from StartAddress.
1462
1463 **/
1464 UINTN
1465 EFIAPI
1466 PciExpressReadBuffer (
1467 IN UINTN StartAddress,
1468 IN UINTN Size,
1469 OUT VOID *Buffer
1470 )
1471 {
1472 UINTN ReturnValue;
1473
1474 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1475
1476 if (Size == 0) {
1477 return Size;
1478 }
1479
1480 ASSERT (Buffer != NULL);
1481
1482 //
1483 // Save Size for return
1484 //
1485 ReturnValue = Size;
1486
1487 if ((StartAddress & 1) != 0) {
1488 //
1489 // Read a byte if StartAddress is byte aligned
1490 //
1491 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
1492 StartAddress += sizeof (UINT8);
1493 Size -= sizeof (UINT8);
1494 Buffer = (UINT8*)Buffer + 1;
1495 }
1496
1497 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1498 //
1499 // Read a word if StartAddress is word aligned
1500 //
1501 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
1502
1503 StartAddress += sizeof (UINT16);
1504 Size -= sizeof (UINT16);
1505 Buffer = (UINT16*)Buffer + 1;
1506 }
1507
1508 while (Size >= sizeof (UINT32)) {
1509 //
1510 // Read as many double words as possible
1511 //
1512 WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress));
1513
1514 StartAddress += sizeof (UINT32);
1515 Size -= sizeof (UINT32);
1516 Buffer = (UINT32*)Buffer + 1;
1517 }
1518
1519 if (Size >= sizeof (UINT16)) {
1520 //
1521 // Read the last remaining word if exist
1522 //
1523 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
1524 StartAddress += sizeof (UINT16);
1525 Size -= sizeof (UINT16);
1526 Buffer = (UINT16*)Buffer + 1;
1527 }
1528
1529 if (Size >= sizeof (UINT8)) {
1530 //
1531 // Read the last remaining byte if exist
1532 //
1533 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
1534 }
1535
1536 return ReturnValue;
1537 }
1538
1539 /**
1540 Copies the data in a caller supplied buffer to a specified range of PCI
1541 configuration space.
1542
1543 Writes the range of PCI configuration registers specified by StartAddress and
1544 Size from the buffer specified by Buffer. This function only allows the PCI
1545 configuration registers from a single PCI function to be written. Size is
1546 returned. When possible 32-bit PCI configuration write cycles are used to
1547 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1548 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1549 and the end of the range.
1550
1551 If StartAddress > 0x0FFFFFFF, then ASSERT().
1552 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1553 If Size > 0 and Buffer is NULL, then ASSERT().
1554
1555 @param StartAddress Starting address that encodes the PCI Bus, Device,
1556 Function and Register.
1557 @param Size Size in bytes of the transfer.
1558 @param Buffer Pointer to a buffer containing the data to write.
1559
1560 @return Size written to StartAddress.
1561
1562 **/
1563 UINTN
1564 EFIAPI
1565 PciExpressWriteBuffer (
1566 IN UINTN StartAddress,
1567 IN UINTN Size,
1568 IN VOID *Buffer
1569 )
1570 {
1571 UINTN ReturnValue;
1572
1573 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1574
1575 if (Size == 0) {
1576 return 0;
1577 }
1578
1579 ASSERT (Buffer != NULL);
1580
1581 //
1582 // Save Size for return
1583 //
1584 ReturnValue = Size;
1585
1586 if ((StartAddress & 1) != 0) {
1587 //
1588 // Write a byte if StartAddress is byte aligned
1589 //
1590 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
1591 StartAddress += sizeof (UINT8);
1592 Size -= sizeof (UINT8);
1593 Buffer = (UINT8*)Buffer + 1;
1594 }
1595
1596 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1597 //
1598 // Write a word if StartAddress is word aligned
1599 //
1600 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1601 StartAddress += sizeof (UINT16);
1602 Size -= sizeof (UINT16);
1603 Buffer = (UINT16*)Buffer + 1;
1604 }
1605
1606 while (Size >= sizeof (UINT32)) {
1607 //
1608 // Write as many double words as possible
1609 //
1610 PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));
1611 StartAddress += sizeof (UINT32);
1612 Size -= sizeof (UINT32);
1613 Buffer = (UINT32*)Buffer + 1;
1614 }
1615
1616 if (Size >= sizeof (UINT16)) {
1617 //
1618 // Write the last remaining word if exist
1619 //
1620 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1621 StartAddress += sizeof (UINT16);
1622 Size -= sizeof (UINT16);
1623 Buffer = (UINT16*)Buffer + 1;
1624 }
1625
1626 if (Size >= sizeof (UINT8)) {
1627 //
1628 // Write the last remaining byte if exist
1629 //
1630 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
1631 }
1632
1633 return ReturnValue;
1634 }