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