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