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