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