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