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