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