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