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