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