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