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