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