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