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