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