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