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