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