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