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