]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/DeviceIoOnPciRootBridgeIoThunk/DeviceIoOnPciRootBridgeIoThunk.c
Fix comparisons of enumerated types which may cause warnings for some compilers.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / DeviceIoOnPciRootBridgeIoThunk / DeviceIoOnPciRootBridgeIoThunk.c
CommitLineData
fd4ae733 1/** @file\r
6ea838c3 2Module produces Device I/O on top of PCI Root Bridge I/O for Segment 0 only.\r
3This is a valid assumption because many of the EFI 1.02/EFI 1.10 systems that may have provided \r
4Device I/O were single segment platforms. The goal of the ECP is to provide compatibility with the \r
5drivers/apps that may have used Device I/O.\r
fd4ae733 6\r
7Device I/O is on list of deprecated protocols for UEFI 2.0 and later.\r
8This module module layers Device I/O on top of PCI Root Bridge I/O (Segment 0)\r
9 Use if:\r
8598a1ed 10 There are no EDK modules present that produces Device I/O\r
fd4ae733 11 EFI drivers included that consume Device I/O\r
12 Platform required to support EFI drivers that consume Device I/O\r
13 Platform required to support EFI applications that consume Device I/O\r
14\r
3d78c020 15Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
584d5652 16This program and the accompanying materials\r
fd4ae733 17are licensed and made available under the terms and conditions of the BSD License\r
18which accompanies this distribution. The full text of the license may be found at\r
19http://opensource.org/licenses/bsd-license.php\r
20\r
21THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
22WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
23\r
24**/\r
25\r
26#include <PiDxe.h>\r
ac10c727 27#include <IndustryStandard/Pci.h>\r
fd4ae733 28#include <Protocol/DeviceIo.h>\r
29#include <Protocol/PciRootBridgeIo.h>\r
30#include <Library/BaseLib.h>\r
31#include <Library/BaseMemoryLib.h>\r
32#include <Library/DebugLib.h>\r
33#include <Library/UefiBootServicesTableLib.h>\r
34#include <Library/UefiDriverEntryPoint.h>\r
35#include <Library/UefiLib.h>\r
36#include <Library/MemoryAllocationLib.h>\r
37#include <Library/DevicePathLib.h>\r
38\r
39\r
40/**\r
41 Perform reading memory mapped I/O space of device.\r
42\r
43 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
44 @param Width Width of I/O operations.\r
45 @param Address The base address of I/O operations.\r
46 @param Count The number of I/O operations to perform. Bytes\r
47 moves is Width size * Count, starting at Address.\r
48 @param Buffer The destination buffer to store results.\r
49\r
50 @retval EFI_SUCCESS The data was read from the device.\r
51 @retval EFI_INVALID_PARAMETER Width is invalid.\r
52 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
53 resources.\r
54\r
55**/\r
56EFI_STATUS\r
57EFIAPI\r
58DeviceIoMemRead (\r
59 IN EFI_DEVICE_IO_PROTOCOL *This,\r
60 IN EFI_IO_WIDTH Width,\r
61 IN UINT64 Address,\r
62 IN UINTN Count,\r
63 IN OUT VOID *Buffer\r
e00e1d46 64 );\r
fd4ae733 65\r
66\r
67/**\r
68 Perform writing memory mapped I/O space of device.\r
69\r
70 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
71 @param Width Width of I/O operations.\r
72 @param Address The base address of I/O operations.\r
73 @param Count The number of I/O operations to perform. Bytes\r
74 moves is Width size * Count, starting at Address.\r
75 @param Buffer The source buffer of data to be written.\r
76\r
77 @retval EFI_SUCCESS The data was written to the device.\r
78 @retval EFI_INVALID_PARAMETER Width is invalid.\r
79 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
80 resources.\r
81\r
82**/\r
83EFI_STATUS\r
84EFIAPI\r
85DeviceIoMemWrite (\r
86 IN EFI_DEVICE_IO_PROTOCOL *This,\r
87 IN EFI_IO_WIDTH Width,\r
88 IN UINT64 Address,\r
89 IN UINTN Count,\r
90 IN OUT VOID *Buffer\r
e00e1d46 91 );\r
fd4ae733 92\r
93/**\r
94 Perform reading I/O space of device.\r
95\r
96 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
97 @param Width Width of I/O operations.\r
98 @param Address The base address of I/O operations.\r
99 @param Count The number of I/O operations to perform. Bytes\r
100 moves is Width size * Count, starting at Address.\r
101 @param Buffer The destination buffer to store results.\r
102\r
103 @retval EFI_SUCCESS The data was read from the device.\r
104 @retval EFI_INVALID_PARAMETER Width is invalid.\r
105 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
106 resources.\r
107\r
108**/\r
109EFI_STATUS\r
110EFIAPI\r
111DeviceIoIoRead (\r
112 IN EFI_DEVICE_IO_PROTOCOL *This,\r
113 IN EFI_IO_WIDTH Width,\r
114 IN UINT64 Address,\r
115 IN UINTN Count,\r
116 IN OUT VOID *Buffer\r
e00e1d46 117 );\r
fd4ae733 118\r
119/**\r
120 Perform writing I/O space of device.\r
121\r
122 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
123 @param Width Width of I/O operations.\r
124 @param Address The base address of I/O operations.\r
125 @param Count The number of I/O operations to perform. Bytes\r
126 moves is Width size * Count, starting at Address.\r
127 @param Buffer The source buffer of data to be written.\r
128\r
129 @retval EFI_SUCCESS The data was written to the device.\r
130 @retval EFI_INVALID_PARAMETER Width is invalid.\r
131 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
132 resources.\r
133\r
134**/\r
135EFI_STATUS\r
136EFIAPI\r
137DeviceIoIoWrite (\r
138 IN EFI_DEVICE_IO_PROTOCOL *This,\r
139 IN EFI_IO_WIDTH Width,\r
140 IN UINT64 Address,\r
141 IN UINTN Count,\r
142 IN OUT VOID *Buffer\r
e00e1d46 143 );\r
fd4ae733 144\r
145/**\r
146 Perform reading PCI configuration space of device\r
147\r
148 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
149 @param Width Width of I/O operations.\r
150 @param Address The base address of I/O operations.\r
151 @param Count The number of I/O operations to perform. Bytes\r
152 moves is Width size * Count, starting at Address.\r
153 @param Buffer The destination buffer to store results.\r
154\r
155 @retval EFI_SUCCESS The data was read from the device.\r
156 @retval EFI_INVALID_PARAMETER Width is invalid.\r
157 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
158 resources.\r
159\r
160**/\r
161EFI_STATUS\r
162EFIAPI\r
163DeviceIoPciRead (\r
164 IN EFI_DEVICE_IO_PROTOCOL *This,\r
165 IN EFI_IO_WIDTH Width,\r
166 IN UINT64 Address,\r
167 IN UINTN Count,\r
168 IN OUT VOID *Buffer\r
e00e1d46 169 );\r
fd4ae733 170\r
171/**\r
172 Perform writing PCI configuration space of device.\r
173\r
174 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
175 @param Width Width of I/O operations.\r
176 @param Address The base address of I/O operations.\r
177 @param Count The number of I/O operations to perform. Bytes\r
178 moves is Width size * Count, starting at Address.\r
179 @param Buffer The source buffer of data to be written.\r
180\r
181 @retval EFI_SUCCESS The data was written to the device.\r
182 @retval EFI_INVALID_PARAMETER Width is invalid.\r
183 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
184 resources.\r
185\r
186**/\r
187EFI_STATUS\r
188EFIAPI\r
189DeviceIoPciWrite (\r
190 IN EFI_DEVICE_IO_PROTOCOL *This,\r
191 IN EFI_IO_WIDTH Width,\r
192 IN UINT64 Address,\r
193 IN UINTN Count,\r
194 IN OUT VOID *Buffer\r
e00e1d46 195 );\r
fd4ae733 196\r
197/**\r
198 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.\r
199\r
200 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
201 @param Address The PCI configuration space address of the device\r
202 whose Device Path is going to be returned.\r
203 @param PciDevicePath A pointer to the pointer for the EFI Device Path\r
204 for PciAddress. Memory for the Device Path is\r
205 allocated from the pool.\r
206\r
207 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI\r
208 Device Path.\r
209 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device\r
210 Path.\r
211 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
212 of resources.\r
213\r
214**/\r
215EFI_STATUS\r
216EFIAPI\r
217DeviceIoPciDevicePath (\r
218 IN EFI_DEVICE_IO_PROTOCOL *This,\r
219 IN UINT64 Address,\r
220 IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath\r
e00e1d46 221 );\r
fd4ae733 222\r
223/**\r
224 Provides the device-specific addresses needed to access system memory.\r
225\r
226 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
227 @param Operation Indicates if the bus master is going to read or\r
228 write to system memory.\r
229 @param HostAddress The system memory address to map to the device.\r
230 @param NumberOfBytes On input the number of bytes to map. On output the\r
231 number of bytes that were mapped.\r
232 @param DeviceAddress The resulting map address for the bus master\r
233 device to use to access the hosts HostAddress.\r
234 @param Mapping A resulting value to pass to Unmap().\r
235\r
236 @retval EFI_SUCCESS The range was mapped for the returned\r
237 NumberOfBytes.\r
238 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.\r
239 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common\r
240 buffer.\r
241 @retval EFI_DEVICE_ERROR The system hardware could not map the requested\r
242 address.\r
243 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
244 of resources.\r
245\r
246**/\r
247EFI_STATUS\r
248EFIAPI\r
249DeviceIoMap (\r
250 IN EFI_DEVICE_IO_PROTOCOL *This,\r
251 IN EFI_IO_OPERATION_TYPE Operation,\r
252 IN EFI_PHYSICAL_ADDRESS *HostAddress,\r
253 IN OUT UINTN *NumberOfBytes,\r
254 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
255 OUT VOID **Mapping\r
e00e1d46 256 );\r
fd4ae733 257\r
258/**\r
259 Completes the Map() operation and releases any corresponding resources.\r
260\r
261 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
262 @param Mapping The mapping value returned from Map().\r
263\r
264 @retval EFI_SUCCESS The range was unmapped.\r
265 @retval EFI_DEVICE_ERROR The data was not committed to the target system\r
266 memory.\r
267\r
268**/\r
269EFI_STATUS\r
270EFIAPI\r
271DeviceIoUnmap (\r
272 IN EFI_DEVICE_IO_PROTOCOL *This,\r
273 IN VOID *Mapping\r
e00e1d46 274 );\r
fd4ae733 275\r
276/**\r
277 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.\r
278\r
279 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
280 @param Type The type allocation to perform.\r
281 @param MemoryType The type of memory to allocate,\r
282 EfiBootServicesData or EfiRuntimeServicesData.\r
283 @param Pages The number of pages to allocate.\r
284 @param PhysicalAddress A pointer to store the base address of the\r
285 allocated range.\r
286\r
287 @retval EFI_SUCCESS The requested memory pages were allocated.\r
288 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
289 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.\r
290 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on\r
291 this platform.\r
292\r
293**/\r
294EFI_STATUS\r
295EFIAPI\r
296DeviceIoAllocateBuffer (\r
297 IN EFI_DEVICE_IO_PROTOCOL *This,\r
298 IN EFI_ALLOCATE_TYPE Type,\r
299 IN EFI_MEMORY_TYPE MemoryType,\r
300 IN UINTN Pages,\r
301 IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress\r
e00e1d46 302 );\r
fd4ae733 303\r
304/**\r
305 Flushes any posted write data to the device.\r
306\r
307 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
308\r
309 @retval EFI_SUCCESS The buffers were flushed.\r
310 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware\r
311 error.\r
312\r
313**/\r
314EFI_STATUS\r
315EFIAPI\r
316DeviceIoFlush (\r
317 IN EFI_DEVICE_IO_PROTOCOL *This\r
e00e1d46 318 );\r
fd4ae733 319\r
320/**\r
321 Frees pages that were allocated with AllocateBuffer().\r
322\r
323 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
324 @param Pages The number of pages to free.\r
325 @param HostAddress The base address of the range to free.\r
326\r
327 @retval EFI_SUCCESS The requested memory pages were freed.\r
328 @retval EFI_NOT_FOUND The requested memory pages were not allocated with\r
329 AllocateBuffer().\r
330 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is\r
331 invalid.\r
332\r
333**/\r
334EFI_STATUS\r
335EFIAPI\r
336DeviceIoFreeBuffer (\r
337 IN EFI_DEVICE_IO_PROTOCOL *This,\r
338 IN UINTN Pages,\r
339 IN EFI_PHYSICAL_ADDRESS HostAddress\r
e00e1d46 340 );\r
fd4ae733 341\r
342\r
a3a83173 343#define DEVICE_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('D', 'e', 'I', 'O')\r
fd4ae733 344\r
345typedef struct {\r
346 UINTN Signature;\r
347 EFI_DEVICE_IO_PROTOCOL DeviceIo;\r
348 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
349 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
350 UINT16 PrimaryBus;\r
351 UINT16 SubordinateBus;\r
352} DEVICE_IO_PRIVATE_DATA;\r
353\r
354#define DEVICE_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DEVICE_IO_PRIVATE_DATA, DeviceIo, DEVICE_IO_PRIVATE_DATA_SIGNATURE)\r
355\r
356#define MAX_COMMON_BUFFER 0x00000000FFFFFFFF\r
357\r
358\r
359EFI_EVENT mPciRootBridgeIoRegistration;\r
360\r
361//\r
362// Device Io Volume Protocol template\r
363//\r
364DEVICE_IO_PRIVATE_DATA gDeviceIoPrivateDataTemplate = {\r
365 DEVICE_IO_PRIVATE_DATA_SIGNATURE,\r
366 {\r
367 {\r
368 DeviceIoMemRead,\r
369 DeviceIoMemWrite\r
370 },\r
371 {\r
372 DeviceIoIoRead,\r
373 DeviceIoIoWrite \r
374 },\r
375 {\r
376 DeviceIoPciRead,\r
377 DeviceIoPciWrite, \r
378 },\r
379 DeviceIoMap,\r
380 DeviceIoPciDevicePath,\r
381 DeviceIoUnmap,\r
382 DeviceIoAllocateBuffer,\r
383 DeviceIoFlush,\r
384 DeviceIoFreeBuffer\r
385 },\r
386 NULL, // PciRootBridgeIo\r
387 NULL, // DevicePath\r
388 0, // PrimaryBus\r
389 255 // SubordinateBus\r
390};\r
391\r
26a76fbc
LG
392/**\r
393 This notification function is invoked when an instance of the\r
394 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL is produced. It installs another instance of the\r
395 EFI_DEVICE_IO_PROTOCOL on the same handle.\r
396\r
397 @param Event The event that occured\r
398 @param Context Context of event. Not used in this nofication function.\r
399\r
400**/\r
fd4ae733 401VOID\r
402EFIAPI\r
403PciRootBridgeIoNotificationEvent (\r
404 IN EFI_EVENT Event,\r
405 IN VOID *Context\r
406 )\r
407{\r
408 EFI_STATUS Status;\r
409 UINTN BufferSize;\r
410 EFI_HANDLE Handle;\r
411 DEVICE_IO_PRIVATE_DATA *Private;\r
412 EFI_DEVICE_IO_PROTOCOL *DeviceIo;\r
413 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
414\r
415 while (TRUE) {\r
416 BufferSize = sizeof (Handle);\r
417 Status = gBS->LocateHandle (\r
418 ByRegisterNotify,\r
419 &gEfiPciRootBridgeIoProtocolGuid,\r
420 mPciRootBridgeIoRegistration,\r
421 &BufferSize,\r
422 &Handle\r
423 );\r
424 if (EFI_ERROR (Status)) {\r
425 //\r
426 // Exit Path of While Loop....\r
427 //\r
428 break;\r
429 }\r
430\r
431 //\r
432 // Skip this handle if the Device Io Protocol is already installed\r
433 //\r
434 Status = gBS->HandleProtocol (\r
435 Handle,\r
436 &gEfiDeviceIoProtocolGuid,\r
437 (VOID **)&DeviceIo\r
438 );\r
439 if (!EFI_ERROR (Status)) {\r
440 continue;\r
441 }\r
442\r
443 //\r
444 // Retrieve the Pci Root Bridge IO Protocol\r
445 //\r
446 Status = gBS->HandleProtocol (\r
447 Handle,\r
448 &gEfiPciRootBridgeIoProtocolGuid,\r
449 (VOID **)&PciRootBridgeIo\r
450 );\r
451 ASSERT_EFI_ERROR (Status);\r
452\r
453 //\r
6ea838c3 454 // We only install Device IO for PCI bus in Segment 0.\r
455 // See the file description at @file for details.\r
fd4ae733 456 //\r
457 if (PciRootBridgeIo->SegmentNumber != 0) {\r
458 continue;\r
459 }\r
460\r
461 //\r
462 // Allocate private data structure\r
463 //\r
464 Private = AllocateCopyPool (sizeof (DEVICE_IO_PRIVATE_DATA), &gDeviceIoPrivateDataTemplate);\r
465 if (Private == NULL) {\r
466 continue;\r
467 }\r
468\r
2b534a7c 469 Private->PciRootBridgeIo = PciRootBridgeIo;\r
470\r
fd4ae733 471 Status = gBS->HandleProtocol (\r
472 Handle,\r
473 &gEfiDevicePathProtocolGuid,\r
474 (VOID **) &Private->DevicePath\r
475 );\r
476\r
477 //\r
478 // Install Device Io onto same handle\r
479 //\r
480 Status = gBS->InstallMultipleProtocolInterfaces (\r
481 &Handle,\r
482 &gEfiDeviceIoProtocolGuid,\r
483 &Private->DeviceIo,\r
484 NULL\r
485 );\r
486 ASSERT_EFI_ERROR (Status);\r
487 }\r
488}\r
489\r
490/**\r
491 The user Entry Point for DXE driver. The user code starts with this function\r
492 as the real entry point for the image goes into a library that calls this \r
493 function.\r
494\r
495 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
496 @param[in] SystemTable A pointer to the EFI System Table.\r
497 \r
498 @retval EFI_SUCCESS The entry point is executed successfully.\r
499 @retval other Some error occurs when executing this entry point.\r
500\r
501**/\r
502EFI_STATUS\r
503EFIAPI\r
504InitializeDeviceIo (\r
505 IN EFI_HANDLE ImageHandle,\r
506 IN EFI_SYSTEM_TABLE *SystemTable\r
507 )\r
508{\r
509 EfiCreateProtocolNotifyEvent (\r
510 &gEfiPciRootBridgeIoProtocolGuid,\r
511 TPL_CALLBACK,\r
512 PciRootBridgeIoNotificationEvent,\r
513 NULL,\r
514 &mPciRootBridgeIoRegistration\r
515 );\r
516 return EFI_SUCCESS;\r
517}\r
518\r
519\r
520/**\r
521 Perform reading memory mapped I/O space of device.\r
522\r
523 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
524 @param Width Width of I/O operations.\r
525 @param Address The base address of I/O operations.\r
526 @param Count The number of I/O operations to perform. Bytes\r
527 moves is Width size * Count, starting at Address.\r
528 @param Buffer The destination buffer to store results.\r
529\r
530 @retval EFI_SUCCESS The data was read from the device.\r
531 @retval EFI_INVALID_PARAMETER Width is invalid.\r
532 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
533 resources.\r
534\r
535**/\r
536EFI_STATUS\r
537EFIAPI\r
538DeviceIoMemRead (\r
539 IN EFI_DEVICE_IO_PROTOCOL *This,\r
540 IN EFI_IO_WIDTH Width,\r
541 IN UINT64 Address,\r
542 IN UINTN Count,\r
543 IN OUT VOID *Buffer\r
544 )\r
545{\r
546 EFI_STATUS Status;\r
547 DEVICE_IO_PRIVATE_DATA *Private;\r
548\r
549 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
550\r
551 if (Width > MMIO_COPY_UINT64) {\r
552 return EFI_INVALID_PARAMETER;\r
553 }\r
554 if (Width >= MMIO_COPY_UINT8) {\r
e16c7fa3 555 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);\r
fd4ae733 556 Status = Private->PciRootBridgeIo->CopyMem (\r
557 Private->PciRootBridgeIo,\r
558 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
559 (UINT64) (UINTN) Buffer,\r
560 Address,\r
561 Count\r
562 );\r
563 } else {\r
564 Status = Private->PciRootBridgeIo->Mem.Read (\r
565 Private->PciRootBridgeIo,\r
566 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
567 Address,\r
568 Count,\r
569 Buffer\r
570 );\r
571 }\r
572\r
573 return Status;\r
574}\r
575\r
576\r
577\r
578\r
579/**\r
580 Perform writing memory mapped I/O space of device.\r
581\r
582 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
583 @param Width Width of I/O operations.\r
584 @param Address The base address of I/O operations.\r
585 @param Count The number of I/O operations to perform. Bytes\r
586 moves is Width size * Count, starting at Address.\r
587 @param Buffer The source buffer of data to be written.\r
588\r
589 @retval EFI_SUCCESS The data was written to the device.\r
590 @retval EFI_INVALID_PARAMETER Width is invalid.\r
591 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
592 resources.\r
593\r
594**/\r
595EFI_STATUS\r
596EFIAPI\r
597DeviceIoMemWrite (\r
598 IN EFI_DEVICE_IO_PROTOCOL *This,\r
599 IN EFI_IO_WIDTH Width,\r
600 IN UINT64 Address,\r
601 IN UINTN Count,\r
602 IN OUT VOID *Buffer\r
603 )\r
604{\r
605 EFI_STATUS Status;\r
606 DEVICE_IO_PRIVATE_DATA *Private;\r
607\r
608 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
609\r
610 if (Width > MMIO_COPY_UINT64) {\r
611 return EFI_INVALID_PARAMETER;\r
612 }\r
613 if (Width >= MMIO_COPY_UINT8) {\r
e16c7fa3 614 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);\r
fd4ae733 615 Status = Private->PciRootBridgeIo->CopyMem (\r
616 Private->PciRootBridgeIo,\r
617 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
618 Address,\r
619 (UINT64) (UINTN) Buffer,\r
620 Count\r
621 );\r
622 } else {\r
623 Status = Private->PciRootBridgeIo->Mem.Write (\r
624 Private->PciRootBridgeIo,\r
625 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
626 Address,\r
627 Count,\r
628 Buffer\r
629 );\r
630 }\r
631\r
632 return Status;\r
633}\r
634\r
635\r
636/**\r
637 Perform reading I/O space of device.\r
638\r
639 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
640 @param Width Width of I/O operations.\r
641 @param Address The base address of I/O operations.\r
642 @param Count The number of I/O operations to perform. Bytes\r
643 moves is Width size * Count, starting at Address.\r
644 @param Buffer The destination buffer to store results.\r
645\r
646 @retval EFI_SUCCESS The data was read from the device.\r
647 @retval EFI_INVALID_PARAMETER Width is invalid.\r
648 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
649 resources.\r
650\r
651**/\r
652EFI_STATUS\r
653EFIAPI\r
654DeviceIoIoRead (\r
655 IN EFI_DEVICE_IO_PROTOCOL *This,\r
656 IN EFI_IO_WIDTH Width,\r
657 IN UINT64 Address,\r
658 IN UINTN Count,\r
659 IN OUT VOID *Buffer\r
660 )\r
661{\r
662 EFI_STATUS Status;\r
663 DEVICE_IO_PRIVATE_DATA *Private;\r
664\r
665 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
666\r
667 if (Width >= MMIO_COPY_UINT8) {\r
668 return EFI_INVALID_PARAMETER;\r
669 }\r
670\r
671 Status = Private->PciRootBridgeIo->Io.Read (\r
672 Private->PciRootBridgeIo,\r
673 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
674 Address,\r
675 Count,\r
676 Buffer\r
677 );\r
678\r
679 return Status;\r
680}\r
681\r
682\r
683/**\r
684 Perform writing I/O space of device.\r
685\r
686 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
687 @param Width Width of I/O operations.\r
688 @param Address The base address of I/O operations.\r
689 @param Count The number of I/O operations to perform. Bytes\r
690 moves is Width size * Count, starting at Address.\r
691 @param Buffer The source buffer of data to be written.\r
692\r
693 @retval EFI_SUCCESS The data was written to the device.\r
694 @retval EFI_INVALID_PARAMETER Width is invalid.\r
695 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
696 resources.\r
697\r
698**/\r
699EFI_STATUS\r
700EFIAPI\r
701DeviceIoIoWrite (\r
702 IN EFI_DEVICE_IO_PROTOCOL *This,\r
703 IN EFI_IO_WIDTH Width,\r
704 IN UINT64 Address,\r
705 IN UINTN Count,\r
706 IN OUT VOID *Buffer\r
707 )\r
708{\r
709 EFI_STATUS Status;\r
710 DEVICE_IO_PRIVATE_DATA *Private;\r
711\r
712 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
713\r
714 if (Width >= MMIO_COPY_UINT8) {\r
715 return EFI_INVALID_PARAMETER;\r
716 }\r
717\r
718 Status = Private->PciRootBridgeIo->Io.Write (\r
719 Private->PciRootBridgeIo,\r
720 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
721 Address,\r
722 Count,\r
723 Buffer\r
724 );\r
725\r
726 return Status;\r
727}\r
728\r
729\r
730/**\r
731 Perform reading PCI configuration space of device\r
732\r
733 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
734 @param Width Width of I/O operations.\r
735 @param Address The base address of I/O operations.\r
736 @param Count The number of I/O operations to perform. Bytes\r
737 moves is Width size * Count, starting at Address.\r
738 @param Buffer The destination buffer to store results.\r
739\r
740 @retval EFI_SUCCESS The data was read from the device.\r
741 @retval EFI_INVALID_PARAMETER Width is invalid.\r
742 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
743 resources.\r
744\r
745**/\r
746EFI_STATUS\r
747EFIAPI\r
748DeviceIoPciRead (\r
749 IN EFI_DEVICE_IO_PROTOCOL *This,\r
750 IN EFI_IO_WIDTH Width,\r
751 IN UINT64 Address,\r
752 IN UINTN Count,\r
753 IN OUT VOID *Buffer\r
754 )\r
755{\r
756 EFI_STATUS Status;\r
757 DEVICE_IO_PRIVATE_DATA *Private;\r
758\r
759 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
760\r
3d78c020 761 if ((UINT32)Width >= MMIO_COPY_UINT8) {\r
fd4ae733 762 return EFI_INVALID_PARAMETER;\r
763 }\r
764\r
765 Status = Private->PciRootBridgeIo->Pci.Read (\r
766 Private->PciRootBridgeIo,\r
767 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
768 Address,\r
769 Count,\r
770 Buffer\r
771 );\r
772\r
773 return Status;\r
774}\r
775\r
776\r
777/**\r
778 Perform writing PCI configuration space of device.\r
779\r
780 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
781 @param Width Width of I/O operations.\r
782 @param Address The base address of I/O operations.\r
783 @param Count The number of I/O operations to perform. Bytes\r
784 moves is Width size * Count, starting at Address.\r
785 @param Buffer The source buffer of data to be written.\r
786\r
787 @retval EFI_SUCCESS The data was written to the device.\r
788 @retval EFI_INVALID_PARAMETER Width is invalid.\r
789 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
790 resources.\r
791\r
792**/\r
793EFI_STATUS\r
794EFIAPI\r
795DeviceIoPciWrite (\r
796 IN EFI_DEVICE_IO_PROTOCOL *This,\r
797 IN EFI_IO_WIDTH Width,\r
798 IN UINT64 Address,\r
799 IN UINTN Count,\r
800 IN OUT VOID *Buffer\r
801 )\r
802{\r
803 EFI_STATUS Status;\r
804 DEVICE_IO_PRIVATE_DATA *Private;\r
805\r
806 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
807\r
3d78c020 808 if ((UINT32)Width >= MMIO_COPY_UINT8) {\r
fd4ae733 809 return EFI_INVALID_PARAMETER;\r
810 }\r
811\r
812 Status = Private->PciRootBridgeIo->Pci.Write (\r
813 Private->PciRootBridgeIo,\r
814 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
815 Address,\r
816 Count,\r
817 Buffer\r
818 );\r
819\r
820 return Status;\r
821}\r
822\r
823\r
824/**\r
825 Append a PCI device path node to another device path.\r
826\r
827 @param Private A pointer to DEVICE_IO_PRIVATE_DATA instance.\r
828 @param Bus PCI bus number of the device.\r
829 @param Device PCI device number of the device.\r
830 @param Function PCI function number of the device.\r
831 @param DevicePath Original device path which will be appended a PCI\r
832 device path node.\r
833 @param BridgePrimaryBus Primary bus number of the bridge.\r
834 @param BridgeSubordinateBus Subordinate bus number of the bridge.\r
835\r
836 @return Pointer to the appended PCI device path.\r
837\r
838**/\r
839EFI_DEVICE_PATH_PROTOCOL *\r
840AppendPciDevicePath (\r
841 IN DEVICE_IO_PRIVATE_DATA *Private,\r
842 IN UINT8 Bus,\r
843 IN UINT8 Device,\r
844 IN UINT8 Function,\r
845 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
846 IN OUT UINT16 *BridgePrimaryBus,\r
847 IN OUT UINT16 *BridgeSubordinateBus\r
848 )\r
849{\r
850 UINT16 ThisBus;\r
851 UINT8 ThisDevice;\r
852 UINT8 ThisFunc;\r
853 UINT64 Address;\r
854 PCI_TYPE01 PciBridge;\r
855 PCI_TYPE01 *PciPtr;\r
856 EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath;\r
857 PCI_DEVICE_PATH PciNode;\r
858\r
859 PciPtr = &PciBridge;\r
860 for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) {\r
861 for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) {\r
862 for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) {\r
863 Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0);\r
864 ZeroMem (PciPtr, sizeof (PCI_TYPE01));\r
865 Private->DeviceIo.Pci.Read (\r
866 &Private->DeviceIo,\r
867 IO_UINT32,\r
868 Address,\r
869 1,\r
870 &(PciPtr->Hdr.VendorId)\r
871 );\r
872 if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) {\r
873 break;\r
874 }\r
875 if (PciPtr->Hdr.VendorId == 0xffff) {\r
876 continue;\r
877 } else {\r
878 Private->DeviceIo.Pci.Read (\r
879 &Private->DeviceIo,\r
880 IO_UINT32,\r
881 Address,\r
882 sizeof (PCI_TYPE01) / sizeof (UINT32),\r
883 PciPtr\r
884 );\r
885 if (IS_PCI_BRIDGE (PciPtr)) {\r
886 if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) {\r
887\r
888 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
889 PciNode.Header.SubType = HW_PCI_DP;\r
890 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
891\r
892 PciNode.Device = ThisDevice;\r
893 PciNode.Function = ThisFunc;\r
894 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);\r
895\r
896 *BridgePrimaryBus = PciPtr->Bridge.SecondaryBus;\r
897 *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;\r
898 return ReturnDevicePath;\r
899 }\r
900 }\r
de558d9d 901 if (ThisFunc == 0 && ((PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) != HEADER_TYPE_MULTI_FUNCTION)) {\r
fd4ae733 902 //\r
903 // Skip sub functions, this is not a multi function device\r
904 //\r
905 ThisFunc = 8;\r
906 }\r
907 }\r
908 }\r
909 }\r
910 }\r
911\r
912 ZeroMem (&PciNode, sizeof (PciNode));\r
913 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
914 PciNode.Header.SubType = HW_PCI_DP;\r
915 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
916 PciNode.Device = Device;\r
917 PciNode.Function = Function;\r
918\r
919 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);\r
920\r
921 *BridgePrimaryBus = 0xffff;\r
922 *BridgeSubordinateBus = 0xffff;\r
923 return ReturnDevicePath;\r
924}\r
925\r
926\r
927/**\r
928 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.\r
929\r
930 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
931 @param Address The PCI configuration space address of the device\r
932 whose Device Path is going to be returned.\r
933 @param PciDevicePath A pointer to the pointer for the EFI Device Path\r
934 for PciAddress. Memory for the Device Path is\r
935 allocated from the pool.\r
936\r
937 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI\r
938 Device Path.\r
939 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device\r
940 Path.\r
941 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
942 of resources.\r
943\r
944**/\r
945EFI_STATUS\r
946EFIAPI\r
947DeviceIoPciDevicePath (\r
948 IN EFI_DEVICE_IO_PROTOCOL *This,\r
949 IN UINT64 Address,\r
950 IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath\r
951 )\r
952{\r
953 DEVICE_IO_PRIVATE_DATA *Private;\r
954 UINT16 PrimaryBus;\r
955 UINT16 SubordinateBus;\r
956 UINT8 Bus;\r
957 UINT8 Device;\r
958 UINT8 Func;\r
959\r
960 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
961\r
962 Bus = (UINT8) (((UINT32) Address >> 24) & 0xff);\r
963 Device = (UINT8) (((UINT32) Address >> 16) & 0xff);\r
964 Func = (UINT8) (((UINT32) Address >> 8) & 0xff);\r
965\r
966 if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) {\r
967 return EFI_UNSUPPORTED;\r
968 }\r
969\r
970 *PciDevicePath = Private->DevicePath;\r
971 PrimaryBus = Private->PrimaryBus;\r
972 SubordinateBus = Private->SubordinateBus;\r
973 do {\r
974 *PciDevicePath = AppendPciDevicePath (\r
975 Private,\r
976 Bus,\r
977 Device,\r
978 Func,\r
979 *PciDevicePath,\r
980 &PrimaryBus,\r
981 &SubordinateBus\r
982 );\r
983 if (*PciDevicePath == NULL) {\r
984 return EFI_OUT_OF_RESOURCES;\r
985 }\r
986 } while (PrimaryBus != 0xffff);\r
987\r
988 return EFI_SUCCESS;\r
989}\r
990\r
991\r
992/**\r
993 Provides the device-specific addresses needed to access system memory.\r
994\r
995 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
996 @param Operation Indicates if the bus master is going to read or\r
997 write to system memory.\r
998 @param HostAddress The system memory address to map to the device.\r
999 @param NumberOfBytes On input the number of bytes to map. On output the\r
1000 number of bytes that were mapped.\r
1001 @param DeviceAddress The resulting map address for the bus master\r
1002 device to use to access the hosts HostAddress.\r
1003 @param Mapping A resulting value to pass to Unmap().\r
1004\r
1005 @retval EFI_SUCCESS The range was mapped for the returned\r
1006 NumberOfBytes.\r
1007 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.\r
1008 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common\r
1009 buffer.\r
1010 @retval EFI_DEVICE_ERROR The system hardware could not map the requested\r
1011 address.\r
1012 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
1013 of resources.\r
1014\r
1015**/\r
1016EFI_STATUS\r
1017EFIAPI\r
1018DeviceIoMap (\r
1019 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1020 IN EFI_IO_OPERATION_TYPE Operation,\r
1021 IN EFI_PHYSICAL_ADDRESS *HostAddress,\r
1022 IN OUT UINTN *NumberOfBytes,\r
1023 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
1024 OUT VOID **Mapping\r
1025 )\r
1026{\r
1027 EFI_STATUS Status;\r
1028 DEVICE_IO_PRIVATE_DATA *Private;\r
1029\r
1030 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1031\r
3d78c020 1032 if ((UINT32)Operation > EfiBusMasterCommonBuffer) {\r
fd4ae733 1033 return EFI_INVALID_PARAMETER;\r
1034 }\r
1035\r
1036 if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) {\r
1037 return EFI_UNSUPPORTED;\r
1038 }\r
1039\r
1040 Status = Private->PciRootBridgeIo->Map (\r
1041 Private->PciRootBridgeIo,\r
1042 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
1043 (VOID *) (UINTN) (*HostAddress),\r
1044 NumberOfBytes,\r
1045 DeviceAddress,\r
1046 Mapping\r
1047 );\r
1048\r
1049 return Status;\r
1050}\r
1051\r
1052\r
1053/**\r
1054 Completes the Map() operation and releases any corresponding resources.\r
1055\r
1056 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1057 @param Mapping The mapping value returned from Map().\r
1058\r
1059 @retval EFI_SUCCESS The range was unmapped.\r
1060 @retval EFI_DEVICE_ERROR The data was not committed to the target system\r
1061 memory.\r
1062\r
1063**/\r
1064EFI_STATUS\r
1065EFIAPI\r
1066DeviceIoUnmap (\r
1067 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1068 IN VOID *Mapping\r
1069 )\r
1070{\r
1071 EFI_STATUS Status;\r
1072 DEVICE_IO_PRIVATE_DATA *Private;\r
1073\r
1074 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1075\r
1076 Status = Private->PciRootBridgeIo->Unmap (\r
1077 Private->PciRootBridgeIo,\r
1078 Mapping\r
1079 );\r
1080\r
1081 return Status;\r
1082}\r
1083\r
1084\r
1085/**\r
1086 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.\r
1087\r
1088 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1089 @param Type The type allocation to perform.\r
1090 @param MemoryType The type of memory to allocate,\r
1091 EfiBootServicesData or EfiRuntimeServicesData.\r
1092 @param Pages The number of pages to allocate.\r
1093 @param PhysicalAddress A pointer to store the base address of the\r
1094 allocated range.\r
1095\r
1096 @retval EFI_SUCCESS The requested memory pages were allocated.\r
1097 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
1098 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.\r
1099 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on\r
1100 this platform.\r
1101\r
1102**/\r
1103EFI_STATUS\r
1104EFIAPI\r
1105DeviceIoAllocateBuffer (\r
1106 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1107 IN EFI_ALLOCATE_TYPE Type,\r
1108 IN EFI_MEMORY_TYPE MemoryType,\r
1109 IN UINTN Pages,\r
1110 IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress\r
1111 )\r
1112{\r
6ea838c3 1113 EFI_STATUS Status;\r
1114 EFI_PHYSICAL_ADDRESS HostAddress;\r
1115 DEVICE_IO_PRIVATE_DATA *Private;\r
1116 VOID *HostAddress2;\r
1117\r
1118 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
fd4ae733 1119\r
1120 HostAddress = *PhysicalAddress;\r
1121\r
1122 if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {\r
1123 return EFI_INVALID_PARAMETER;\r
1124 }\r
1125\r
3d78c020 1126 if ((UINT32)Type >= MaxAllocateType) {\r
fd4ae733 1127 return EFI_INVALID_PARAMETER;\r
1128 }\r
1129\r
1130 if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) {\r
1131 return EFI_UNSUPPORTED;\r
1132 }\r
1133\r
1134 if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) {\r
1135 Type = AllocateMaxAddress;\r
1136 HostAddress = MAX_COMMON_BUFFER;\r
1137 }\r
1138\r
6ea838c3 1139 HostAddress2 = (VOID *) (UINTN) (HostAddress);\r
1140 Status = Private->PciRootBridgeIo->AllocateBuffer (\r
1141 Private->PciRootBridgeIo,\r
1142 Type,\r
1143 MemoryType,\r
1144 Pages,\r
1145 &HostAddress2,\r
1146 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
1147 EFI_PCI_ATTRIBUTE_MEMORY_CACHED\r
1148 );\r
1149 \r
fd4ae733 1150 if (EFI_ERROR (Status)) {\r
1151 return Status;\r
1152 }\r
1153\r
1154\r
6ea838c3 1155 *PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress2;\r
fd4ae733 1156\r
1157 return EFI_SUCCESS;\r
1158}\r
1159\r
1160\r
1161/**\r
1162 Flushes any posted write data to the device.\r
1163\r
1164 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1165\r
1166 @retval EFI_SUCCESS The buffers were flushed.\r
1167 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware\r
1168 error.\r
1169\r
1170**/\r
1171EFI_STATUS\r
1172EFIAPI\r
1173DeviceIoFlush (\r
1174 IN EFI_DEVICE_IO_PROTOCOL *This\r
1175 )\r
1176{\r
1177 EFI_STATUS Status;\r
1178 DEVICE_IO_PRIVATE_DATA *Private;\r
1179\r
1180 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1181\r
1182 Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo);\r
1183\r
1184 return Status;\r
1185}\r
1186\r
1187\r
1188/**\r
1189 Frees pages that were allocated with AllocateBuffer().\r
1190\r
1191 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1192 @param Pages The number of pages to free.\r
1193 @param HostAddress The base address of the range to free.\r
1194\r
1195 @retval EFI_SUCCESS The requested memory pages were freed.\r
1196 @retval EFI_NOT_FOUND The requested memory pages were not allocated with\r
1197 AllocateBuffer().\r
1198 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is\r
1199 invalid.\r
1200\r
1201**/\r
1202EFI_STATUS\r
1203EFIAPI\r
1204DeviceIoFreeBuffer (\r
1205 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1206 IN UINTN Pages,\r
1207 IN EFI_PHYSICAL_ADDRESS HostAddress\r
1208 )\r
1209{\r
6ea838c3 1210 DEVICE_IO_PRIVATE_DATA *Private;\r
1211\r
1212 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1213\r
fd4ae733 1214 if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {\r
1215 return EFI_INVALID_PARAMETER;\r
1216 }\r
1217\r
6ea838c3 1218 return Private->PciRootBridgeIo->FreeBuffer (\r
1219 Private->PciRootBridgeIo,\r
1220 Pages,\r
1221 (VOID *) (UINTN) HostAddress\r
1222 );\r
1223\r
fd4ae733 1224}\r
1225\r