]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePciSegmentLibPci/PciSegmentLib.c
MdePkg/PciSegmentLib: Fix typo in function header comments
[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
ebdde8ff 5 Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
32fa5588
RN
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
ebdde8ff 78 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
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
ebdde8ff 102 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
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
ebdde8ff 131 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
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
ebdde8ff 157 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
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
ebdde8ff
RN
186 @param Address 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
32fa5588
RN
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
ebdde8ff 216 @param Address PCI configuration register to read.\r
32fa5588
RN
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
ebdde8ff 250 @param Address PCI configuration register to write.\r
32fa5588
RN
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
ebdde8ff 255 @param Value New value of the bit field.\r
32fa5588
RN
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
ebdde8ff 292 @param Address PCI configuration register to write.\r
32fa5588
RN
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
ebdde8ff 334 @param Address PCI configuration register to write.\r
32fa5588
RN
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
ebdde8ff 361 bitwise OR, and writes the result back to the bit field in the 8-bit port.\r
32fa5588
RN
362\r
363 Reads the 8-bit PCI configuration register specified by Address, performs a\r
364 bitwise AND followed by a bitwise OR between the read result and\r
365 the value specified by AndData, and writes the result to the 8-bit PCI\r
366 configuration register specified by Address. The value written to the PCI\r
367 configuration register is returned. This function must guarantee that all PCI\r
368 read and write operations are serialized. Extra left bits in both AndData and\r
369 OrData are stripped.\r
370\r
371 If any reserved bits in Address are set, then ASSERT().\r
372 If StartBit is greater than 7, then ASSERT().\r
373 If EndBit is greater than 7, then ASSERT().\r
374 If EndBit is less than StartBit, then ASSERT().\r
375 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
376 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
377\r
ebdde8ff 378 @param Address PCI configuration register to write.\r
32fa5588
RN
379 @param StartBit The ordinal of the least significant bit in the bit field.\r
380 Range 0..7.\r
381 @param EndBit The ordinal of the most significant bit in the bit field.\r
382 Range 0..7.\r
383 @param AndData The value to AND with the PCI configuration register.\r
384 @param OrData The value to OR with the result of the AND operation.\r
385\r
386 @return The value written back to the PCI configuration register.\r
387\r
388**/\r
389UINT8\r
390EFIAPI\r
391PciSegmentBitFieldAndThenOr8 (\r
392 IN UINT64 Address,\r
393 IN UINTN StartBit,\r
394 IN UINTN EndBit,\r
395 IN UINT8 AndData,\r
396 IN UINT8 OrData\r
397 )\r
398{\r
399 return PciSegmentWrite8 (\r
400 Address,\r
401 BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)\r
402 );\r
403}\r
404\r
405/**\r
406 Reads a 16-bit PCI configuration register.\r
407\r
408 Reads and returns the 16-bit PCI configuration register specified by Address.\r
409 This function must guarantee that all PCI read and write operations are serialized.\r
410\r
411 If any reserved bits in Address are set, then ASSERT().\r
412 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
413\r
ebdde8ff 414 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
415\r
416 @return The 16-bit PCI configuration register specified by Address.\r
417\r
418**/\r
419UINT16\r
420EFIAPI\r
421PciSegmentRead16 (\r
422 IN UINT64 Address\r
423 )\r
424{\r
425 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
426\r
427 return PciRead16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address));\r
428}\r
429\r
430/**\r
431 Writes a 16-bit PCI configuration register.\r
432\r
433 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.\r
434 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
435\r
436 If any reserved bits in Address are set, then ASSERT().\r
437 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
438\r
ebdde8ff 439 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
440 @param Value The value to write.\r
441\r
442 @return The parameter of Value.\r
443\r
444**/\r
445UINT16\r
446EFIAPI\r
447PciSegmentWrite16 (\r
448 IN UINT64 Address,\r
449 IN UINT16 Value\r
450 )\r
451{\r
452 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
453\r
454 return PciWrite16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value);\r
455}\r
456\r
457/**\r
458 Performs a bitwise OR of a 16-bit PCI configuration register with\r
459 a 16-bit value.\r
460\r
461 Reads the 16-bit PCI configuration register specified by Address, performs a\r
ebdde8ff
RN
462 bitwise OR between the read result and the value specified by OrData, and\r
463 writes the result to the 16-bit PCI configuration register specified by Address.\r
464 The value written to the PCI configuration register is returned. This function\r
465 must guarantee that all PCI read and write operations are serialized.\r
32fa5588
RN
466\r
467 If any reserved bits in Address are set, then ASSERT().\r
468 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
469\r
ebdde8ff 470 @param Address Address that encodes the PCI Segment, Bus, Device, Function and\r
32fa5588
RN
471 Register.\r
472 @param OrData The value to OR with the PCI configuration register.\r
473\r
474 @return The value written back to the PCI configuration register.\r
475\r
476**/\r
477UINT16\r
478EFIAPI\r
479PciSegmentOr16 (\r
480 IN UINT64 Address,\r
481 IN UINT16 OrData\r
482 )\r
483{\r
484 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));\r
485}\r
486\r
487/**\r
488 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.\r
489\r
490 Reads the 16-bit PCI configuration register specified by Address,\r
491 performs a bitwise AND between the read result and the value specified by AndData,\r
492 and writes the result to the 16-bit PCI configuration register specified by Address.\r
493 The value written to the PCI configuration register is returned.\r
494 This function must guarantee that all PCI read and write operations are serialized.\r
495\r
496 If any reserved bits in Address are set, then ASSERT().\r
497 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
498\r
ebdde8ff 499 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
500 @param AndData The value to AND with the PCI configuration register.\r
501\r
502 @return The value written to the PCI configuration register.\r
503\r
504**/\r
505UINT16\r
506EFIAPI\r
507PciSegmentAnd16 (\r
508 IN UINT64 Address,\r
509 IN UINT16 AndData\r
510 )\r
511{\r
512 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));\r
513}\r
514\r
515/**\r
516 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,\r
517 followed a bitwise OR with another 16-bit value.\r
518\r
519 Reads the 16-bit PCI configuration register specified by Address,\r
520 performs a bitwise AND between the read result and the value specified by AndData,\r
521 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
522 and writes the result to the 16-bit PCI configuration register specified by Address.\r
523 The value written to the PCI configuration register is returned.\r
524 This function must guarantee that all PCI read and write operations are serialized.\r
525\r
526 If any reserved bits in Address are set, then ASSERT().\r
527 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
528\r
ebdde8ff
RN
529 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
530 @param AndData The value to AND with the PCI configuration register.\r
32fa5588
RN
531 @param OrData The value to OR with the PCI configuration register.\r
532\r
533 @return The value written to the PCI configuration register.\r
534\r
535**/\r
536UINT16\r
537EFIAPI\r
538PciSegmentAndThenOr16 (\r
539 IN UINT64 Address,\r
540 IN UINT16 AndData,\r
541 IN UINT16 OrData\r
542 )\r
543{\r
544 return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));\r
545}\r
546\r
547/**\r
548 Reads a bit field of a PCI configuration register.\r
549\r
550 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
551 specified by the StartBit and the EndBit. The value of the bit field is\r
552 returned.\r
553\r
554 If any reserved bits in Address are set, then ASSERT().\r
555 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
556 If StartBit is greater than 15, then ASSERT().\r
557 If EndBit is greater than 15, then ASSERT().\r
558 If EndBit is less than StartBit, then ASSERT().\r
559\r
ebdde8ff 560 @param Address PCI configuration register to read.\r
32fa5588
RN
561 @param StartBit The ordinal of the least significant bit in the bit field.\r
562 Range 0..15.\r
563 @param EndBit The ordinal of the most significant bit in the bit field.\r
564 Range 0..15.\r
565\r
566 @return The value of the bit field read from the PCI configuration register.\r
567\r
568**/\r
569UINT16\r
570EFIAPI\r
571PciSegmentBitFieldRead16 (\r
572 IN UINT64 Address,\r
573 IN UINTN StartBit,\r
574 IN UINTN EndBit\r
575 )\r
576{\r
577 return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);\r
578}\r
579\r
580/**\r
581 Writes a bit field to a PCI configuration register.\r
582\r
583 Writes Value to the bit field of the PCI configuration register. The bit\r
584 field is specified by the StartBit and the EndBit. All other bits in the\r
585 destination PCI configuration register are preserved. The new value of the\r
586 16-bit register is returned.\r
587\r
588 If any reserved bits in Address are set, then ASSERT().\r
589 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
590 If StartBit is greater than 15, then ASSERT().\r
591 If EndBit is greater than 15, then ASSERT().\r
592 If EndBit is less than StartBit, then ASSERT().\r
593 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
594\r
ebdde8ff 595 @param Address PCI configuration register to write.\r
32fa5588
RN
596 @param StartBit The ordinal of the least significant bit in the bit field.\r
597 Range 0..15.\r
598 @param EndBit The ordinal of the most significant bit in the bit field.\r
599 Range 0..15.\r
ebdde8ff 600 @param Value New value of the bit field.\r
32fa5588
RN
601\r
602 @return The value written back to the PCI configuration register.\r
603\r
604**/\r
605UINT16\r
606EFIAPI\r
607PciSegmentBitFieldWrite16 (\r
608 IN UINT64 Address,\r
609 IN UINTN StartBit,\r
610 IN UINTN EndBit,\r
611 IN UINT16 Value\r
612 )\r
613{\r
614 return PciSegmentWrite16 (\r
615 Address,\r
616 BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)\r
617 );\r
618}\r
619\r
620/**\r
ebdde8ff
RN
621 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, writes\r
622 the result back to the bit field in the 16-bit port.\r
623\r
624 Reads the 16-bit PCI configuration register specified by Address, performs a\r
625 bitwise OR between the read result and the value specified by\r
626 OrData, and writes the result to the 16-bit PCI configuration register\r
627 specified by Address. The value written to the PCI configuration register is\r
628 returned. This function must guarantee that all PCI read and write operations\r
629 are serialized. Extra left bits in OrData are stripped.\r
32fa5588
RN
630\r
631 If any reserved bits in Address are set, then ASSERT().\r
632 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
633 If StartBit is greater than 15, then ASSERT().\r
634 If EndBit is greater than 15, then ASSERT().\r
635 If EndBit is less than StartBit, then ASSERT().\r
636 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
637\r
ebdde8ff 638 @param Address PCI configuration register to write.\r
32fa5588
RN
639 @param StartBit The ordinal of the least significant bit in the bit field.\r
640 Range 0..15.\r
641 @param EndBit The ordinal of the most significant bit in the bit field.\r
642 Range 0..15.\r
643 @param OrData The value to OR with the PCI configuration register.\r
644\r
645 @return The value written back to the PCI configuration register.\r
646\r
647**/\r
648UINT16\r
649EFIAPI\r
650PciSegmentBitFieldOr16 (\r
651 IN UINT64 Address,\r
652 IN UINTN StartBit,\r
653 IN UINTN EndBit,\r
654 IN UINT16 OrData\r
655 )\r
656{\r
657 return PciSegmentWrite16 (\r
658 Address,\r
659 BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)\r
660 );\r
661}\r
662\r
663/**\r
ebdde8ff
RN
664 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
665 AND, writes the result back to the bit field in the 16-bit register.\r
32fa5588 666\r
ebdde8ff
RN
667 Reads the 16-bit PCI configuration register specified by Address, performs a\r
668 bitwise AND between the read result and the value specified by AndData, and\r
669 writes the result to the 16-bit PCI configuration register specified by\r
670 Address. The value written to the PCI configuration register is returned.\r
671 This function must guarantee that all PCI read and write operations are\r
672 serialized. Extra left bits in AndData are stripped.\r
32fa5588
RN
673\r
674 If any reserved bits in Address are set, then ASSERT().\r
675 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
ebdde8ff
RN
676 If StartBit is greater than 15, then ASSERT().\r
677 If EndBit is greater than 15, then ASSERT().\r
32fa5588
RN
678 If EndBit is less than StartBit, then ASSERT().\r
679 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
680\r
ebdde8ff 681 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588 682 @param StartBit The ordinal of the least significant bit in the bit field.\r
ebdde8ff 683 Range 0..15.\r
32fa5588 684 @param EndBit The ordinal of the most significant bit in the bit field.\r
ebdde8ff
RN
685 Range 0..15.\r
686 @param AndData The value to AND with the PCI configuration register.\r
32fa5588 687\r
ebdde8ff 688 @return The value written back to the PCI configuration register.\r
32fa5588
RN
689\r
690**/\r
691UINT16\r
692EFIAPI\r
693PciSegmentBitFieldAnd16 (\r
694 IN UINT64 Address,\r
695 IN UINTN StartBit,\r
696 IN UINTN EndBit,\r
697 IN UINT16 AndData\r
698 )\r
699{\r
700 return PciSegmentWrite16 (\r
701 Address,\r
702 BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)\r
703 );\r
704}\r
705\r
706/**\r
707 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
708 bitwise OR, and writes the result back to the bit field in the\r
709 16-bit port.\r
710\r
711 Reads the 16-bit PCI configuration register specified by Address, performs a\r
712 bitwise AND followed by a bitwise OR between the read result and\r
713 the value specified by AndData, and writes the result to the 16-bit PCI\r
714 configuration register specified by Address. The value written to the PCI\r
715 configuration register is returned. This function must guarantee that all PCI\r
716 read and write operations are serialized. Extra left bits in both AndData and\r
717 OrData are stripped.\r
718\r
719 If any reserved bits in Address are set, then ASSERT().\r
720 If StartBit is greater than 15, then ASSERT().\r
721 If EndBit is greater than 15, then ASSERT().\r
722 If EndBit is less than StartBit, then ASSERT().\r
723 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
724 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
725\r
ebdde8ff 726 @param Address PCI configuration register to write.\r
32fa5588
RN
727 @param StartBit The ordinal of the least significant bit in the bit field.\r
728 Range 0..15.\r
729 @param EndBit The ordinal of the most significant bit in the bit field.\r
730 Range 0..15.\r
731 @param AndData The value to AND with the PCI configuration register.\r
732 @param OrData The value to OR with the result of the AND operation.\r
733\r
734 @return The value written back to the PCI configuration register.\r
735\r
736**/\r
737UINT16\r
738EFIAPI\r
739PciSegmentBitFieldAndThenOr16 (\r
740 IN UINT64 Address,\r
741 IN UINTN StartBit,\r
742 IN UINTN EndBit,\r
743 IN UINT16 AndData,\r
744 IN UINT16 OrData\r
745 )\r
746{\r
747 return PciSegmentWrite16 (\r
748 Address,\r
749 BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)\r
750 );\r
751}\r
752\r
753/**\r
754 Reads a 32-bit PCI configuration register.\r
755\r
756 Reads and returns the 32-bit PCI configuration register specified by Address.\r
757 This function must guarantee that all PCI read and write operations are serialized.\r
758\r
759 If any reserved bits in Address are set, then ASSERT().\r
760 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
761\r
ebdde8ff 762 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
763\r
764 @return The 32-bit PCI configuration register specified by Address.\r
765\r
766**/\r
767UINT32\r
768EFIAPI\r
769PciSegmentRead32 (\r
770 IN UINT64 Address\r
771 )\r
772{\r
773 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
774\r
775 return PciRead32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address));\r
776}\r
777\r
778/**\r
779 Writes a 32-bit PCI configuration register.\r
780\r
781 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.\r
782 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
783\r
784 If any reserved bits in Address are set, then ASSERT().\r
785 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
786\r
ebdde8ff 787 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
788 @param Value The value to write.\r
789\r
790 @return The parameter of Value.\r
791\r
792**/\r
793UINT32\r
794EFIAPI\r
795PciSegmentWrite32 (\r
796 IN UINT64 Address,\r
797 IN UINT32 Value\r
798 )\r
799{\r
800 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
801\r
802 return PciWrite32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value);\r
803}\r
804\r
805/**\r
806 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.\r
807\r
808 Reads the 32-bit PCI configuration register specified by Address,\r
809 performs a bitwise OR between the read result and the value specified by OrData,\r
810 and writes the result to the 32-bit PCI configuration register specified by Address.\r
811 The value written to the PCI configuration register is returned.\r
812 This function must guarantee that all PCI read and write operations are serialized.\r
813\r
814 If any reserved bits in Address are set, then ASSERT().\r
815 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
816\r
ebdde8ff 817 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
818 @param OrData The value to OR with the PCI configuration register.\r
819\r
820 @return The value written to the PCI configuration register.\r
821\r
822**/\r
823UINT32\r
824EFIAPI\r
825PciSegmentOr32 (\r
826 IN UINT64 Address,\r
827 IN UINT32 OrData\r
828 )\r
829{\r
830 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);\r
831}\r
832\r
833/**\r
834 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.\r
835\r
836 Reads the 32-bit PCI configuration register specified by Address,\r
837 performs a bitwise AND between the read result and the value specified by AndData,\r
838 and writes the result to the 32-bit PCI configuration register specified by Address.\r
839 The value written to the PCI configuration register is returned.\r
840 This function must guarantee that all PCI read and write operations are serialized.\r
841\r
842 If any reserved bits in Address are set, then ASSERT().\r
843 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
844\r
ebdde8ff 845 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
846 @param AndData The value to AND with the PCI configuration register.\r
847\r
848 @return The value written to the PCI configuration register.\r
849\r
850**/\r
851UINT32\r
852EFIAPI\r
853PciSegmentAnd32 (\r
854 IN UINT64 Address,\r
855 IN UINT32 AndData\r
856 )\r
857{\r
858 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);\r
859}\r
860\r
861/**\r
862 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,\r
863 followed a bitwise OR with another 32-bit value.\r
864\r
865 Reads the 32-bit PCI configuration register specified by Address,\r
866 performs a bitwise AND between the read result and the value specified by AndData,\r
867 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
868 and writes the result to the 32-bit PCI configuration register specified by Address.\r
869 The value written to the PCI configuration register is returned.\r
870 This function must guarantee that all PCI read and write operations are serialized.\r
871\r
872 If any reserved bits in Address are set, then ASSERT().\r
873 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
874\r
ebdde8ff 875 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
876 @param AndData The value to AND with the PCI configuration register.\r
877 @param OrData The value to OR with the PCI configuration register.\r
878\r
879 @return The value written to the PCI configuration register.\r
880\r
881**/\r
882UINT32\r
883EFIAPI\r
884PciSegmentAndThenOr32 (\r
885 IN UINT64 Address,\r
886 IN UINT32 AndData,\r
887 IN UINT32 OrData\r
888 )\r
889{\r
890 return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);\r
891}\r
892\r
893/**\r
894 Reads a bit field of a PCI configuration register.\r
895\r
896 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
897 specified by the StartBit and the EndBit. The value of the bit field is\r
898 returned.\r
899\r
900 If any reserved bits in Address are set, then ASSERT().\r
901 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
902 If StartBit is greater than 31, then ASSERT().\r
903 If EndBit is greater than 31, then ASSERT().\r
904 If EndBit is less than StartBit, then ASSERT().\r
905\r
ebdde8ff 906 @param Address PCI configuration register to read.\r
32fa5588
RN
907 @param StartBit The ordinal of the least significant bit in the bit field.\r
908 Range 0..31.\r
909 @param EndBit The ordinal of the most significant bit in the bit field.\r
910 Range 0..31.\r
911\r
912 @return The value of the bit field read from the PCI configuration register.\r
913\r
914**/\r
915UINT32\r
916EFIAPI\r
917PciSegmentBitFieldRead32 (\r
918 IN UINT64 Address,\r
919 IN UINTN StartBit,\r
920 IN UINTN EndBit\r
921 )\r
922{\r
923 return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);\r
924}\r
925\r
926/**\r
927 Writes a bit field to a PCI configuration register.\r
928\r
929 Writes Value to the bit field of the PCI configuration register. The bit\r
930 field is specified by the StartBit and the EndBit. All other bits in the\r
931 destination PCI configuration register are preserved. The new value of the\r
932 32-bit register is returned.\r
933\r
934 If any reserved bits in Address are set, then ASSERT().\r
935 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
936 If StartBit is greater than 31, then ASSERT().\r
937 If EndBit is greater than 31, then ASSERT().\r
938 If EndBit is less than StartBit, then ASSERT().\r
939 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
940\r
ebdde8ff 941 @param Address PCI configuration register to write.\r
32fa5588
RN
942 @param StartBit The ordinal of the least significant bit in the bit field.\r
943 Range 0..31.\r
944 @param EndBit The ordinal of the most significant bit in the bit field.\r
945 Range 0..31.\r
ebdde8ff 946 @param Value New value of the bit field.\r
32fa5588
RN
947\r
948 @return The value written back to the PCI configuration register.\r
949\r
950**/\r
951UINT32\r
952EFIAPI\r
953PciSegmentBitFieldWrite32 (\r
954 IN UINT64 Address,\r
955 IN UINTN StartBit,\r
956 IN UINTN EndBit,\r
957 IN UINT32 Value\r
958 )\r
959{\r
960 return PciSegmentWrite32 (\r
961 Address,\r
962 BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)\r
963 );\r
964}\r
965\r
966/**\r
967 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
968 writes the result back to the bit field in the 32-bit port.\r
969\r
970 Reads the 32-bit PCI configuration register specified by Address, performs a\r
971 bitwise OR between the read result and the value specified by\r
972 OrData, and writes the result to the 32-bit PCI configuration register\r
973 specified by Address. The value written to the PCI configuration register is\r
974 returned. This function must guarantee that all PCI read and write operations\r
975 are serialized. Extra left bits in OrData are stripped.\r
976\r
977 If any reserved bits in Address are set, then ASSERT().\r
978 If StartBit is greater than 31, then ASSERT().\r
979 If EndBit is greater than 31, then ASSERT().\r
980 If EndBit is less than StartBit, then ASSERT().\r
981 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
982\r
ebdde8ff 983 @param Address PCI configuration register to write.\r
32fa5588
RN
984 @param StartBit The ordinal of the least significant bit in the bit field.\r
985 Range 0..31.\r
986 @param EndBit The ordinal of the most significant bit in the bit field.\r
987 Range 0..31.\r
988 @param OrData The value to OR with the PCI configuration register.\r
989\r
990 @return The value written back to the PCI configuration register.\r
991\r
992**/\r
993UINT32\r
994EFIAPI\r
995PciSegmentBitFieldOr32 (\r
996 IN UINT64 Address,\r
997 IN UINTN StartBit,\r
998 IN UINTN EndBit,\r
999 IN UINT32 OrData\r
1000 )\r
1001{\r
1002 return PciSegmentWrite32 (\r
1003 Address,\r
1004 BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)\r
1005 );\r
1006}\r
1007\r
1008/**\r
1009 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1010 AND, and writes the result back to the bit field in the 32-bit register.\r
1011\r
1012\r
1013 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise\r
1014 AND between the read result and the value specified by AndData, and writes the result\r
1015 to the 32-bit PCI configuration register specified by Address. The value written to\r
1016 the PCI configuration register is returned. This function must guarantee that all PCI\r
1017 read and write operations are serialized. Extra left bits in AndData are stripped.\r
1018 If any reserved bits in Address are set, then ASSERT().\r
1019 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1020 If StartBit is greater than 31, then ASSERT().\r
1021 If EndBit is greater than 31, then ASSERT().\r
1022 If EndBit is less than StartBit, then ASSERT().\r
1023 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1024\r
ebdde8ff 1025 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
32fa5588
RN
1026 @param StartBit The ordinal of the least significant bit in the bit field.\r
1027 Range 0..31.\r
1028 @param EndBit The ordinal of the most significant bit in the bit field.\r
1029 Range 0..31.\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
1037PciSegmentBitFieldAnd32 (\r
1038 IN UINT64 Address,\r
1039 IN UINTN StartBit,\r
1040 IN UINTN EndBit,\r
1041 IN UINT32 AndData\r
1042 )\r
1043{\r
1044 return PciSegmentWrite32 (\r
1045 Address,\r
1046 BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)\r
1047 );\r
1048}\r
1049\r
1050/**\r
1051 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
1052 bitwise OR, and writes the result back to the bit field in the\r
1053 32-bit port.\r
1054\r
1055 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1056 bitwise AND followed by a bitwise OR between the read result and\r
1057 the value specified by AndData, and writes the result to the 32-bit PCI\r
1058 configuration register specified by Address. The value written to the PCI\r
1059 configuration register is returned. This function must guarantee that all PCI\r
1060 read and write operations are serialized. Extra left bits in both AndData and\r
1061 OrData are stripped.\r
1062\r
1063 If any reserved bits in Address are set, then ASSERT().\r
1064 If StartBit is greater than 31, then ASSERT().\r
1065 If EndBit is greater than 31, then ASSERT().\r
1066 If EndBit is less than StartBit, then ASSERT().\r
1067 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1068 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1069\r
ebdde8ff 1070 @param Address PCI configuration register to write.\r
32fa5588
RN
1071 @param StartBit The ordinal of the least significant bit in the bit field.\r
1072 Range 0..31.\r
1073 @param EndBit The ordinal of the most significant bit in the bit field.\r
1074 Range 0..31.\r
1075 @param AndData The value to AND with the PCI configuration register.\r
1076 @param OrData The value to OR with the result of the AND operation.\r
1077\r
1078 @return The value written back to the PCI configuration register.\r
1079\r
1080**/\r
1081UINT32\r
1082EFIAPI\r
1083PciSegmentBitFieldAndThenOr32 (\r
1084 IN UINT64 Address,\r
1085 IN UINTN StartBit,\r
1086 IN UINTN EndBit,\r
1087 IN UINT32 AndData,\r
1088 IN UINT32 OrData\r
1089 )\r
1090{\r
1091 return PciSegmentWrite32 (\r
1092 Address,\r
1093 BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)\r
1094 );\r
1095}\r
1096\r
1097/**\r
1098 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1099\r
1100 Reads the range of PCI configuration registers specified by StartAddress and\r
1101 Size into the buffer specified by Buffer. This function only allows the PCI\r
1102 configuration registers from a single PCI function to be read. Size is\r
1103 returned. When possible 32-bit PCI configuration read cycles are used to read\r
1104 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
1105 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1106 end of the range.\r
1107\r
1108 If any reserved bits in StartAddress are set, then ASSERT().\r
1109 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1110 If Size > 0 and Buffer is NULL, then ASSERT().\r
1111\r
ebdde8ff 1112 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,\r
32fa5588 1113 Function and Register.\r
ebdde8ff
RN
1114 @param Size Size in bytes of the transfer.\r
1115 @param Buffer Pointer to a buffer receiving the data read.\r
32fa5588
RN
1116\r
1117 @return Size\r
1118\r
1119**/\r
1120UINTN\r
1121EFIAPI\r
1122PciSegmentReadBuffer (\r
1123 IN UINT64 StartAddress,\r
1124 IN UINTN Size,\r
1125 OUT VOID *Buffer\r
1126 )\r
1127{\r
1128 UINTN ReturnValue;\r
1129\r
1130 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
1131 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1132\r
1133 if (Size == 0) {\r
1134 return Size;\r
1135 }\r
1136\r
1137 ASSERT (Buffer != NULL);\r
1138\r
1139 //\r
1140 // Save Size for return\r
1141 //\r
1142 ReturnValue = Size;\r
1143\r
1144 if ((StartAddress & BIT0) != 0) {\r
1145 //\r
1146 // Read a byte if StartAddress is byte aligned\r
1147 //\r
1148 *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
1149 StartAddress += sizeof (UINT8);\r
1150 Size -= sizeof (UINT8);\r
1151 Buffer = (UINT8*)Buffer + 1;\r
1152 }\r
1153\r
1154 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1155 //\r
1156 // Read a word if StartAddress is word aligned\r
1157 //\r
1158 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
1159 StartAddress += sizeof (UINT16);\r
1160 Size -= sizeof (UINT16);\r
1161 Buffer = (UINT16*)Buffer + 1;\r
1162 }\r
1163\r
1164 while (Size >= sizeof (UINT32)) {\r
1165 //\r
1166 // Read as many double words as possible\r
1167 //\r
1168 WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));\r
1169 StartAddress += sizeof (UINT32);\r
1170 Size -= sizeof (UINT32);\r
1171 Buffer = (UINT32*)Buffer + 1;\r
1172 }\r
1173\r
1174 if (Size >= sizeof (UINT16)) {\r
1175 //\r
1176 // Read the last remaining word if exist\r
1177 //\r
1178 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
1179 StartAddress += sizeof (UINT16);\r
1180 Size -= sizeof (UINT16);\r
1181 Buffer = (UINT16*)Buffer + 1;\r
1182 }\r
1183\r
1184 if (Size >= sizeof (UINT8)) {\r
1185 //\r
1186 // Read the last remaining byte if exist\r
1187 //\r
1188 *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
1189 }\r
1190\r
1191 return ReturnValue;\r
1192}\r
1193\r
1194/**\r
1195 Copies the data in a caller supplied buffer to a specified range of PCI\r
1196 configuration space.\r
1197\r
1198 Writes the range of PCI configuration registers specified by StartAddress and\r
1199 Size from the buffer specified by Buffer. This function only allows the PCI\r
1200 configuration registers from a single PCI function to be written. Size is\r
1201 returned. When possible 32-bit PCI configuration write cycles are used to\r
1202 write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
1203 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1204 and the end of the range.\r
1205\r
1206 If any reserved bits in StartAddress are set, then ASSERT().\r
1207 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1208 If Size > 0 and Buffer is NULL, then ASSERT().\r
1209\r
ebdde8ff 1210 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,\r
32fa5588 1211 Function and Register.\r
ebdde8ff
RN
1212 @param Size Size in bytes of the transfer.\r
1213 @param Buffer Pointer to a buffer containing the data to write.\r
32fa5588
RN
1214\r
1215 @return The parameter of Size.\r
1216\r
1217**/\r
1218UINTN\r
1219EFIAPI\r
1220PciSegmentWriteBuffer (\r
1221 IN UINT64 StartAddress,\r
1222 IN UINTN Size,\r
1223 IN VOID *Buffer\r
1224 )\r
1225{\r
1226 UINTN ReturnValue;\r
1227\r
1228 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
1229 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1230\r
1231 if (Size == 0) {\r
1232 return 0;\r
1233 }\r
1234\r
1235 ASSERT (Buffer != NULL);\r
1236\r
1237 //\r
1238 // Save Size for return\r
1239 //\r
1240 ReturnValue = Size;\r
1241\r
1242 if ((StartAddress & BIT0) != 0) {\r
1243 //\r
1244 // Write a byte if StartAddress is byte aligned\r
1245 //\r
1246 PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer);\r
1247 StartAddress += sizeof (UINT8);\r
1248 Size -= sizeof (UINT8);\r
1249 Buffer = (UINT8*) Buffer + 1;\r
1250 }\r
1251\r
1252 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1253 //\r
1254 // Write a word if StartAddress is word aligned\r
1255 //\r
1256 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1257 StartAddress += sizeof (UINT16);\r
1258 Size -= sizeof (UINT16);\r
1259 Buffer = (UINT16*) Buffer + 1;\r
1260 }\r
1261\r
1262 while (Size >= sizeof (UINT32)) {\r
1263 //\r
1264 // Write as many double words as possible\r
1265 //\r
1266 PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));\r
1267 StartAddress += sizeof (UINT32);\r
1268 Size -= sizeof (UINT32);\r
1269 Buffer = (UINT32*) Buffer + 1;\r
1270 }\r
1271\r
1272 if (Size >= sizeof (UINT16)) {\r
1273 //\r
1274 // Write the last remaining word if exist\r
1275 //\r
1276 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1277 StartAddress += sizeof (UINT16);\r
1278 Size -= sizeof (UINT16);\r
1279 Buffer = (UINT16*) Buffer + 1;\r
1280 }\r
1281\r
1282 if (Size >= sizeof (UINT8)) {\r
1283 //\r
1284 // Write the last remaining byte if exist\r
1285 //\r
1286 PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer);\r
1287 }\r
1288\r
1289 return ReturnValue;\r
1290}\r