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