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