]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/DeviceIoOnPciRootBridgeIoThunk/DeviceIoOnPciRootBridgeIoThunk.c
if module doesn't explicitly depend on specific Pci spec, it should include IndustryS...
[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
10 There are no R8.x modules present that produces Device I/O\r
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
15Copyright (c) 2008 Intel Corporation. <BR>\r
16All rights reserved. This program and the accompanying materials\r
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
392VOID\r
393EFIAPI\r
394PciRootBridgeIoNotificationEvent (\r
395 IN EFI_EVENT Event,\r
396 IN VOID *Context\r
397 )\r
398{\r
399 EFI_STATUS Status;\r
400 UINTN BufferSize;\r
401 EFI_HANDLE Handle;\r
402 DEVICE_IO_PRIVATE_DATA *Private;\r
403 EFI_DEVICE_IO_PROTOCOL *DeviceIo;\r
404 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
405\r
406 while (TRUE) {\r
407 BufferSize = sizeof (Handle);\r
408 Status = gBS->LocateHandle (\r
409 ByRegisterNotify,\r
410 &gEfiPciRootBridgeIoProtocolGuid,\r
411 mPciRootBridgeIoRegistration,\r
412 &BufferSize,\r
413 &Handle\r
414 );\r
415 if (EFI_ERROR (Status)) {\r
416 //\r
417 // Exit Path of While Loop....\r
418 //\r
419 break;\r
420 }\r
421\r
422 //\r
423 // Skip this handle if the Device Io Protocol is already installed\r
424 //\r
425 Status = gBS->HandleProtocol (\r
426 Handle,\r
427 &gEfiDeviceIoProtocolGuid,\r
428 (VOID **)&DeviceIo\r
429 );\r
430 if (!EFI_ERROR (Status)) {\r
431 continue;\r
432 }\r
433\r
434 //\r
435 // Retrieve the Pci Root Bridge IO Protocol\r
436 //\r
437 Status = gBS->HandleProtocol (\r
438 Handle,\r
439 &gEfiPciRootBridgeIoProtocolGuid,\r
440 (VOID **)&PciRootBridgeIo\r
441 );\r
442 ASSERT_EFI_ERROR (Status);\r
443\r
444 //\r
6ea838c3 445 // We only install Device IO for PCI bus in Segment 0.\r
446 // See the file description at @file for details.\r
fd4ae733 447 //\r
448 if (PciRootBridgeIo->SegmentNumber != 0) {\r
449 continue;\r
450 }\r
451\r
452 //\r
453 // Allocate private data structure\r
454 //\r
455 Private = AllocateCopyPool (sizeof (DEVICE_IO_PRIVATE_DATA), &gDeviceIoPrivateDataTemplate);\r
456 if (Private == NULL) {\r
457 continue;\r
458 }\r
459\r
2b534a7c 460 Private->PciRootBridgeIo = PciRootBridgeIo;\r
461\r
fd4ae733 462 Status = gBS->HandleProtocol (\r
463 Handle,\r
464 &gEfiDevicePathProtocolGuid,\r
465 (VOID **) &Private->DevicePath\r
466 );\r
467\r
468 //\r
469 // Install Device Io onto same handle\r
470 //\r
471 Status = gBS->InstallMultipleProtocolInterfaces (\r
472 &Handle,\r
473 &gEfiDeviceIoProtocolGuid,\r
474 &Private->DeviceIo,\r
475 NULL\r
476 );\r
477 ASSERT_EFI_ERROR (Status);\r
478 }\r
479}\r
480\r
481/**\r
482 The user Entry Point for DXE driver. The user code starts with this function\r
483 as the real entry point for the image goes into a library that calls this \r
484 function.\r
485\r
486 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
487 @param[in] SystemTable A pointer to the EFI System Table.\r
488 \r
489 @retval EFI_SUCCESS The entry point is executed successfully.\r
490 @retval other Some error occurs when executing this entry point.\r
491\r
492**/\r
493EFI_STATUS\r
494EFIAPI\r
495InitializeDeviceIo (\r
496 IN EFI_HANDLE ImageHandle,\r
497 IN EFI_SYSTEM_TABLE *SystemTable\r
498 )\r
499{\r
500 EfiCreateProtocolNotifyEvent (\r
501 &gEfiPciRootBridgeIoProtocolGuid,\r
502 TPL_CALLBACK,\r
503 PciRootBridgeIoNotificationEvent,\r
504 NULL,\r
505 &mPciRootBridgeIoRegistration\r
506 );\r
507 return EFI_SUCCESS;\r
508}\r
509\r
510\r
511/**\r
512 Perform reading memory mapped I/O space of device.\r
513\r
514 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
515 @param Width Width of I/O operations.\r
516 @param Address The base address of I/O operations.\r
517 @param Count The number of I/O operations to perform. Bytes\r
518 moves is Width size * Count, starting at Address.\r
519 @param Buffer The destination buffer to store results.\r
520\r
521 @retval EFI_SUCCESS The data was read from the device.\r
522 @retval EFI_INVALID_PARAMETER Width is invalid.\r
523 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
524 resources.\r
525\r
526**/\r
527EFI_STATUS\r
528EFIAPI\r
529DeviceIoMemRead (\r
530 IN EFI_DEVICE_IO_PROTOCOL *This,\r
531 IN EFI_IO_WIDTH Width,\r
532 IN UINT64 Address,\r
533 IN UINTN Count,\r
534 IN OUT VOID *Buffer\r
535 )\r
536{\r
537 EFI_STATUS Status;\r
538 DEVICE_IO_PRIVATE_DATA *Private;\r
539\r
540 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
541\r
542 if (Width > MMIO_COPY_UINT64) {\r
543 return EFI_INVALID_PARAMETER;\r
544 }\r
545 if (Width >= MMIO_COPY_UINT8) {\r
e16c7fa3 546 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);\r
fd4ae733 547 Status = Private->PciRootBridgeIo->CopyMem (\r
548 Private->PciRootBridgeIo,\r
549 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
550 (UINT64) (UINTN) Buffer,\r
551 Address,\r
552 Count\r
553 );\r
554 } else {\r
555 Status = Private->PciRootBridgeIo->Mem.Read (\r
556 Private->PciRootBridgeIo,\r
557 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
558 Address,\r
559 Count,\r
560 Buffer\r
561 );\r
562 }\r
563\r
564 return Status;\r
565}\r
566\r
567\r
568\r
569\r
570/**\r
571 Perform writing memory mapped I/O space of device.\r
572\r
573 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
574 @param Width Width of I/O operations.\r
575 @param Address The base address of I/O operations.\r
576 @param Count The number of I/O operations to perform. Bytes\r
577 moves is Width size * Count, starting at Address.\r
578 @param Buffer The source buffer of data to be written.\r
579\r
580 @retval EFI_SUCCESS The data was written to the device.\r
581 @retval EFI_INVALID_PARAMETER Width is invalid.\r
582 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
583 resources.\r
584\r
585**/\r
586EFI_STATUS\r
587EFIAPI\r
588DeviceIoMemWrite (\r
589 IN EFI_DEVICE_IO_PROTOCOL *This,\r
590 IN EFI_IO_WIDTH Width,\r
591 IN UINT64 Address,\r
592 IN UINTN Count,\r
593 IN OUT VOID *Buffer\r
594 )\r
595{\r
596 EFI_STATUS Status;\r
597 DEVICE_IO_PRIVATE_DATA *Private;\r
598\r
599 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
600\r
601 if (Width > MMIO_COPY_UINT64) {\r
602 return EFI_INVALID_PARAMETER;\r
603 }\r
604 if (Width >= MMIO_COPY_UINT8) {\r
e16c7fa3 605 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);\r
fd4ae733 606 Status = Private->PciRootBridgeIo->CopyMem (\r
607 Private->PciRootBridgeIo,\r
608 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
609 Address,\r
610 (UINT64) (UINTN) Buffer,\r
611 Count\r
612 );\r
613 } else {\r
614 Status = Private->PciRootBridgeIo->Mem.Write (\r
615 Private->PciRootBridgeIo,\r
616 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
617 Address,\r
618 Count,\r
619 Buffer\r
620 );\r
621 }\r
622\r
623 return Status;\r
624}\r
625\r
626\r
627/**\r
628 Perform reading I/O space of device.\r
629\r
630 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
631 @param Width Width of I/O operations.\r
632 @param Address The base address of I/O operations.\r
633 @param Count The number of I/O operations to perform. Bytes\r
634 moves is Width size * Count, starting at Address.\r
635 @param Buffer The destination buffer to store results.\r
636\r
637 @retval EFI_SUCCESS The data was read from the device.\r
638 @retval EFI_INVALID_PARAMETER Width is invalid.\r
639 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
640 resources.\r
641\r
642**/\r
643EFI_STATUS\r
644EFIAPI\r
645DeviceIoIoRead (\r
646 IN EFI_DEVICE_IO_PROTOCOL *This,\r
647 IN EFI_IO_WIDTH Width,\r
648 IN UINT64 Address,\r
649 IN UINTN Count,\r
650 IN OUT VOID *Buffer\r
651 )\r
652{\r
653 EFI_STATUS Status;\r
654 DEVICE_IO_PRIVATE_DATA *Private;\r
655\r
656 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
657\r
658 if (Width >= MMIO_COPY_UINT8) {\r
659 return EFI_INVALID_PARAMETER;\r
660 }\r
661\r
662 Status = Private->PciRootBridgeIo->Io.Read (\r
663 Private->PciRootBridgeIo,\r
664 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
665 Address,\r
666 Count,\r
667 Buffer\r
668 );\r
669\r
670 return Status;\r
671}\r
672\r
673\r
674/**\r
675 Perform writing I/O space of device.\r
676\r
677 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
678 @param Width Width of I/O operations.\r
679 @param Address The base address of I/O operations.\r
680 @param Count The number of I/O operations to perform. Bytes\r
681 moves is Width size * Count, starting at Address.\r
682 @param Buffer The source buffer of data to be written.\r
683\r
684 @retval EFI_SUCCESS The data was written to the device.\r
685 @retval EFI_INVALID_PARAMETER Width is invalid.\r
686 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
687 resources.\r
688\r
689**/\r
690EFI_STATUS\r
691EFIAPI\r
692DeviceIoIoWrite (\r
693 IN EFI_DEVICE_IO_PROTOCOL *This,\r
694 IN EFI_IO_WIDTH Width,\r
695 IN UINT64 Address,\r
696 IN UINTN Count,\r
697 IN OUT VOID *Buffer\r
698 )\r
699{\r
700 EFI_STATUS Status;\r
701 DEVICE_IO_PRIVATE_DATA *Private;\r
702\r
703 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
704\r
705 if (Width >= MMIO_COPY_UINT8) {\r
706 return EFI_INVALID_PARAMETER;\r
707 }\r
708\r
709 Status = Private->PciRootBridgeIo->Io.Write (\r
710 Private->PciRootBridgeIo,\r
711 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
712 Address,\r
713 Count,\r
714 Buffer\r
715 );\r
716\r
717 return Status;\r
718}\r
719\r
720\r
721/**\r
722 Perform reading PCI configuration space of device\r
723\r
724 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
725 @param Width Width of I/O operations.\r
726 @param Address The base address of I/O operations.\r
727 @param Count The number of I/O operations to perform. Bytes\r
728 moves is Width size * Count, starting at Address.\r
729 @param Buffer The destination buffer to store results.\r
730\r
731 @retval EFI_SUCCESS The data was read from the device.\r
732 @retval EFI_INVALID_PARAMETER Width is invalid.\r
733 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
734 resources.\r
735\r
736**/\r
737EFI_STATUS\r
738EFIAPI\r
739DeviceIoPciRead (\r
740 IN EFI_DEVICE_IO_PROTOCOL *This,\r
741 IN EFI_IO_WIDTH Width,\r
742 IN UINT64 Address,\r
743 IN UINTN Count,\r
744 IN OUT VOID *Buffer\r
745 )\r
746{\r
747 EFI_STATUS Status;\r
748 DEVICE_IO_PRIVATE_DATA *Private;\r
749\r
750 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
751\r
752 if (Width < 0 || Width >= MMIO_COPY_UINT8) {\r
753 return EFI_INVALID_PARAMETER;\r
754 }\r
755\r
756 Status = Private->PciRootBridgeIo->Pci.Read (\r
757 Private->PciRootBridgeIo,\r
758 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
759 Address,\r
760 Count,\r
761 Buffer\r
762 );\r
763\r
764 return Status;\r
765}\r
766\r
767\r
768/**\r
769 Perform writing PCI configuration space of device.\r
770\r
771 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
772 @param Width Width of I/O operations.\r
773 @param Address The base address of I/O operations.\r
774 @param Count The number of I/O operations to perform. Bytes\r
775 moves is Width size * Count, starting at Address.\r
776 @param Buffer The source buffer of data to be written.\r
777\r
778 @retval EFI_SUCCESS The data was written to the device.\r
779 @retval EFI_INVALID_PARAMETER Width is invalid.\r
780 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
781 resources.\r
782\r
783**/\r
784EFI_STATUS\r
785EFIAPI\r
786DeviceIoPciWrite (\r
787 IN EFI_DEVICE_IO_PROTOCOL *This,\r
788 IN EFI_IO_WIDTH Width,\r
789 IN UINT64 Address,\r
790 IN UINTN Count,\r
791 IN OUT VOID *Buffer\r
792 )\r
793{\r
794 EFI_STATUS Status;\r
795 DEVICE_IO_PRIVATE_DATA *Private;\r
796\r
797 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
798\r
799 if (Width < 0 || Width >= MMIO_COPY_UINT8) {\r
800 return EFI_INVALID_PARAMETER;\r
801 }\r
802\r
803 Status = Private->PciRootBridgeIo->Pci.Write (\r
804 Private->PciRootBridgeIo,\r
805 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
806 Address,\r
807 Count,\r
808 Buffer\r
809 );\r
810\r
811 return Status;\r
812}\r
813\r
814\r
815/**\r
816 Append a PCI device path node to another device path.\r
817\r
818 @param Private A pointer to DEVICE_IO_PRIVATE_DATA instance.\r
819 @param Bus PCI bus number of the device.\r
820 @param Device PCI device number of the device.\r
821 @param Function PCI function number of the device.\r
822 @param DevicePath Original device path which will be appended a PCI\r
823 device path node.\r
824 @param BridgePrimaryBus Primary bus number of the bridge.\r
825 @param BridgeSubordinateBus Subordinate bus number of the bridge.\r
826\r
827 @return Pointer to the appended PCI device path.\r
828\r
829**/\r
830EFI_DEVICE_PATH_PROTOCOL *\r
831AppendPciDevicePath (\r
832 IN DEVICE_IO_PRIVATE_DATA *Private,\r
833 IN UINT8 Bus,\r
834 IN UINT8 Device,\r
835 IN UINT8 Function,\r
836 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
837 IN OUT UINT16 *BridgePrimaryBus,\r
838 IN OUT UINT16 *BridgeSubordinateBus\r
839 )\r
840{\r
841 UINT16 ThisBus;\r
842 UINT8 ThisDevice;\r
843 UINT8 ThisFunc;\r
844 UINT64 Address;\r
845 PCI_TYPE01 PciBridge;\r
846 PCI_TYPE01 *PciPtr;\r
847 EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath;\r
848 PCI_DEVICE_PATH PciNode;\r
849\r
850 PciPtr = &PciBridge;\r
851 for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) {\r
852 for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) {\r
853 for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) {\r
854 Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0);\r
855 ZeroMem (PciPtr, sizeof (PCI_TYPE01));\r
856 Private->DeviceIo.Pci.Read (\r
857 &Private->DeviceIo,\r
858 IO_UINT32,\r
859 Address,\r
860 1,\r
861 &(PciPtr->Hdr.VendorId)\r
862 );\r
863 if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) {\r
864 break;\r
865 }\r
866 if (PciPtr->Hdr.VendorId == 0xffff) {\r
867 continue;\r
868 } else {\r
869 Private->DeviceIo.Pci.Read (\r
870 &Private->DeviceIo,\r
871 IO_UINT32,\r
872 Address,\r
873 sizeof (PCI_TYPE01) / sizeof (UINT32),\r
874 PciPtr\r
875 );\r
876 if (IS_PCI_BRIDGE (PciPtr)) {\r
877 if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) {\r
878\r
879 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
880 PciNode.Header.SubType = HW_PCI_DP;\r
881 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
882\r
883 PciNode.Device = ThisDevice;\r
884 PciNode.Function = ThisFunc;\r
885 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);\r
886\r
887 *BridgePrimaryBus = PciPtr->Bridge.SecondaryBus;\r
888 *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;\r
889 return ReturnDevicePath;\r
890 }\r
891 }\r
892 if (ThisFunc == 0 && !(PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)) {\r
893 //\r
894 // Skip sub functions, this is not a multi function device\r
895 //\r
896 ThisFunc = 8;\r
897 }\r
898 }\r
899 }\r
900 }\r
901 }\r
902\r
903 ZeroMem (&PciNode, sizeof (PciNode));\r
904 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
905 PciNode.Header.SubType = HW_PCI_DP;\r
906 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
907 PciNode.Device = Device;\r
908 PciNode.Function = Function;\r
909\r
910 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);\r
911\r
912 *BridgePrimaryBus = 0xffff;\r
913 *BridgeSubordinateBus = 0xffff;\r
914 return ReturnDevicePath;\r
915}\r
916\r
917\r
918/**\r
919 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.\r
920\r
921 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
922 @param Address The PCI configuration space address of the device\r
923 whose Device Path is going to be returned.\r
924 @param PciDevicePath A pointer to the pointer for the EFI Device Path\r
925 for PciAddress. Memory for the Device Path is\r
926 allocated from the pool.\r
927\r
928 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI\r
929 Device Path.\r
930 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device\r
931 Path.\r
932 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
933 of resources.\r
934\r
935**/\r
936EFI_STATUS\r
937EFIAPI\r
938DeviceIoPciDevicePath (\r
939 IN EFI_DEVICE_IO_PROTOCOL *This,\r
940 IN UINT64 Address,\r
941 IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath\r
942 )\r
943{\r
944 DEVICE_IO_PRIVATE_DATA *Private;\r
945 UINT16 PrimaryBus;\r
946 UINT16 SubordinateBus;\r
947 UINT8 Bus;\r
948 UINT8 Device;\r
949 UINT8 Func;\r
950\r
951 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
952\r
953 Bus = (UINT8) (((UINT32) Address >> 24) & 0xff);\r
954 Device = (UINT8) (((UINT32) Address >> 16) & 0xff);\r
955 Func = (UINT8) (((UINT32) Address >> 8) & 0xff);\r
956\r
957 if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) {\r
958 return EFI_UNSUPPORTED;\r
959 }\r
960\r
961 *PciDevicePath = Private->DevicePath;\r
962 PrimaryBus = Private->PrimaryBus;\r
963 SubordinateBus = Private->SubordinateBus;\r
964 do {\r
965 *PciDevicePath = AppendPciDevicePath (\r
966 Private,\r
967 Bus,\r
968 Device,\r
969 Func,\r
970 *PciDevicePath,\r
971 &PrimaryBus,\r
972 &SubordinateBus\r
973 );\r
974 if (*PciDevicePath == NULL) {\r
975 return EFI_OUT_OF_RESOURCES;\r
976 }\r
977 } while (PrimaryBus != 0xffff);\r
978\r
979 return EFI_SUCCESS;\r
980}\r
981\r
982\r
983/**\r
984 Provides the device-specific addresses needed to access system memory.\r
985\r
986 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
987 @param Operation Indicates if the bus master is going to read or\r
988 write to system memory.\r
989 @param HostAddress The system memory address to map to the device.\r
990 @param NumberOfBytes On input the number of bytes to map. On output the\r
991 number of bytes that were mapped.\r
992 @param DeviceAddress The resulting map address for the bus master\r
993 device to use to access the hosts HostAddress.\r
994 @param Mapping A resulting value to pass to Unmap().\r
995\r
996 @retval EFI_SUCCESS The range was mapped for the returned\r
997 NumberOfBytes.\r
998 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.\r
999 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common\r
1000 buffer.\r
1001 @retval EFI_DEVICE_ERROR The system hardware could not map the requested\r
1002 address.\r
1003 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
1004 of resources.\r
1005\r
1006**/\r
1007EFI_STATUS\r
1008EFIAPI\r
1009DeviceIoMap (\r
1010 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1011 IN EFI_IO_OPERATION_TYPE Operation,\r
1012 IN EFI_PHYSICAL_ADDRESS *HostAddress,\r
1013 IN OUT UINTN *NumberOfBytes,\r
1014 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
1015 OUT VOID **Mapping\r
1016 )\r
1017{\r
1018 EFI_STATUS Status;\r
1019 DEVICE_IO_PRIVATE_DATA *Private;\r
1020\r
1021 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1022\r
1023 if (Operation < 0 || Operation > EfiBusMasterCommonBuffer) {\r
1024 return EFI_INVALID_PARAMETER;\r
1025 }\r
1026\r
1027 if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) {\r
1028 return EFI_UNSUPPORTED;\r
1029 }\r
1030\r
1031 Status = Private->PciRootBridgeIo->Map (\r
1032 Private->PciRootBridgeIo,\r
1033 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
1034 (VOID *) (UINTN) (*HostAddress),\r
1035 NumberOfBytes,\r
1036 DeviceAddress,\r
1037 Mapping\r
1038 );\r
1039\r
1040 return Status;\r
1041}\r
1042\r
1043\r
1044/**\r
1045 Completes the Map() operation and releases any corresponding resources.\r
1046\r
1047 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1048 @param Mapping The mapping value returned from Map().\r
1049\r
1050 @retval EFI_SUCCESS The range was unmapped.\r
1051 @retval EFI_DEVICE_ERROR The data was not committed to the target system\r
1052 memory.\r
1053\r
1054**/\r
1055EFI_STATUS\r
1056EFIAPI\r
1057DeviceIoUnmap (\r
1058 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1059 IN VOID *Mapping\r
1060 )\r
1061{\r
1062 EFI_STATUS Status;\r
1063 DEVICE_IO_PRIVATE_DATA *Private;\r
1064\r
1065 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1066\r
1067 Status = Private->PciRootBridgeIo->Unmap (\r
1068 Private->PciRootBridgeIo,\r
1069 Mapping\r
1070 );\r
1071\r
1072 return Status;\r
1073}\r
1074\r
1075\r
1076/**\r
1077 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.\r
1078\r
1079 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1080 @param Type The type allocation to perform.\r
1081 @param MemoryType The type of memory to allocate,\r
1082 EfiBootServicesData or EfiRuntimeServicesData.\r
1083 @param Pages The number of pages to allocate.\r
1084 @param PhysicalAddress A pointer to store the base address of the\r
1085 allocated range.\r
1086\r
1087 @retval EFI_SUCCESS The requested memory pages were allocated.\r
1088 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
1089 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.\r
1090 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on\r
1091 this platform.\r
1092\r
1093**/\r
1094EFI_STATUS\r
1095EFIAPI\r
1096DeviceIoAllocateBuffer (\r
1097 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1098 IN EFI_ALLOCATE_TYPE Type,\r
1099 IN EFI_MEMORY_TYPE MemoryType,\r
1100 IN UINTN Pages,\r
1101 IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress\r
1102 )\r
1103{\r
6ea838c3 1104 EFI_STATUS Status;\r
1105 EFI_PHYSICAL_ADDRESS HostAddress;\r
1106 DEVICE_IO_PRIVATE_DATA *Private;\r
1107 VOID *HostAddress2;\r
1108\r
1109 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
fd4ae733 1110\r
1111 HostAddress = *PhysicalAddress;\r
1112\r
1113 if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {\r
1114 return EFI_INVALID_PARAMETER;\r
1115 }\r
1116\r
1117 if ((Type >= MaxAllocateType) || (Type < AllocateAnyPages)) {\r
1118 return EFI_INVALID_PARAMETER;\r
1119 }\r
1120\r
1121 if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) {\r
1122 return EFI_UNSUPPORTED;\r
1123 }\r
1124\r
1125 if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) {\r
1126 Type = AllocateMaxAddress;\r
1127 HostAddress = MAX_COMMON_BUFFER;\r
1128 }\r
1129\r
6ea838c3 1130 HostAddress2 = (VOID *) (UINTN) (HostAddress);\r
1131 Status = Private->PciRootBridgeIo->AllocateBuffer (\r
1132 Private->PciRootBridgeIo,\r
1133 Type,\r
1134 MemoryType,\r
1135 Pages,\r
1136 &HostAddress2,\r
1137 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
1138 EFI_PCI_ATTRIBUTE_MEMORY_CACHED\r
1139 );\r
1140 \r
fd4ae733 1141 if (EFI_ERROR (Status)) {\r
1142 return Status;\r
1143 }\r
1144\r
1145\r
6ea838c3 1146 *PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress2;\r
fd4ae733 1147\r
1148 return EFI_SUCCESS;\r
1149}\r
1150\r
1151\r
1152/**\r
1153 Flushes any posted write data to the device.\r
1154\r
1155 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1156\r
1157 @retval EFI_SUCCESS The buffers were flushed.\r
1158 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware\r
1159 error.\r
1160\r
1161**/\r
1162EFI_STATUS\r
1163EFIAPI\r
1164DeviceIoFlush (\r
1165 IN EFI_DEVICE_IO_PROTOCOL *This\r
1166 )\r
1167{\r
1168 EFI_STATUS Status;\r
1169 DEVICE_IO_PRIVATE_DATA *Private;\r
1170\r
1171 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1172\r
1173 Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo);\r
1174\r
1175 return Status;\r
1176}\r
1177\r
1178\r
1179/**\r
1180 Frees pages that were allocated with AllocateBuffer().\r
1181\r
1182 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1183 @param Pages The number of pages to free.\r
1184 @param HostAddress The base address of the range to free.\r
1185\r
1186 @retval EFI_SUCCESS The requested memory pages were freed.\r
1187 @retval EFI_NOT_FOUND The requested memory pages were not allocated with\r
1188 AllocateBuffer().\r
1189 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is\r
1190 invalid.\r
1191\r
1192**/\r
1193EFI_STATUS\r
1194EFIAPI\r
1195DeviceIoFreeBuffer (\r
1196 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1197 IN UINTN Pages,\r
1198 IN EFI_PHYSICAL_ADDRESS HostAddress\r
1199 )\r
1200{\r
6ea838c3 1201 DEVICE_IO_PRIVATE_DATA *Private;\r
1202\r
1203 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1204\r
fd4ae733 1205 if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {\r
1206 return EFI_INVALID_PARAMETER;\r
1207 }\r
1208\r
6ea838c3 1209 return Private->PciRootBridgeIo->FreeBuffer (\r
1210 Private->PciRootBridgeIo,\r
1211 Pages,\r
1212 (VOID *) (UINTN) HostAddress\r
1213 );\r
1214\r
fd4ae733 1215}\r
1216\r