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