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