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