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