]> git.proxmox.com Git - mirror_edk2.git/blame - CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
IntelFsp2Pkg/Tools: Add BSF bit field support in GenCfgOpt tool
[mirror_edk2.git] / CorebootModulePkg / PciRootBridgeNoEnumerationDxe / DeviceIo.c
CommitLineData
81a23a0f
LL
1/*++
2
3Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
4This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution. The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13
14 DeviceIo.c
15
16Abstract:
17
18 EFI PC-AT PCI Device IO driver
19
20--*/
21#include "PcatPciRootBridge.h"
22#include "DeviceIo.h"
23
24EFI_STATUS
25DeviceIoConstructor (
26 IN EFI_HANDLE Handle,
27 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
28 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
29 IN UINT16 PrimaryBus,
30 IN UINT16 SubordinateBus
31 )
32/*++
33
34Routine Description:
35
36 Initialize and install a Device IO protocol on a empty device path handle.
37
38Arguments:
39
40 Handle - Handle of PCI RootBridge IO instance
41 PciRootBridgeIo - PCI RootBridge IO instance
42 DevicePath - Device Path of PCI RootBridge IO instance
43 PrimaryBus - Primary Bus
44 SubordinateBus - Subordinate Bus
45
46Returns:
47
48 EFI_SUCCESS - This driver is added to ControllerHandle.
49 EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
50 Others - This driver does not support this device.
51
52--*/
53{
54 EFI_STATUS Status;
55 DEVICE_IO_PRIVATE_DATA *Private;
56
57 //
58 // Initialize the Device IO device instance.
59 //
60 Private = AllocateZeroPool (sizeof (DEVICE_IO_PRIVATE_DATA));
61 if (Private == NULL) {
62 return EFI_OUT_OF_RESOURCES;
63 }
64
65 Private->Signature = DEVICE_IO_PRIVATE_DATA_SIGNATURE;
66 Private->Handle = Handle;
67 Private->PciRootBridgeIo = PciRootBridgeIo;
68 Private->DevicePath = DevicePath;
69 Private->PrimaryBus = PrimaryBus;
70 Private->SubordinateBus = SubordinateBus;
71
72 Private->DeviceIo.Mem.Read = DeviceIoMemRead;
73 Private->DeviceIo.Mem.Write = DeviceIoMemWrite;
74 Private->DeviceIo.Io.Read = DeviceIoIoRead;
75 Private->DeviceIo.Io.Write = DeviceIoIoWrite;
76 Private->DeviceIo.Pci.Read = DeviceIoPciRead;
77 Private->DeviceIo.Pci.Write = DeviceIoPciWrite;
78 Private->DeviceIo.PciDevicePath = DeviceIoPciDevicePath;
79 Private->DeviceIo.Map = DeviceIoMap;
80 Private->DeviceIo.Unmap = DeviceIoUnmap;
81 Private->DeviceIo.AllocateBuffer = DeviceIoAllocateBuffer;
82 Private->DeviceIo.Flush = DeviceIoFlush;
83 Private->DeviceIo.FreeBuffer = DeviceIoFreeBuffer;
84
85 //
86 // Install protocol interfaces for the Device IO device.
87 //
88 Status = gBS->InstallMultipleProtocolInterfaces (
89 &Private->Handle,
90 &gEfiDeviceIoProtocolGuid,
91 &Private->DeviceIo,
92 NULL
93 );
94 ASSERT_EFI_ERROR (Status);
95
96 return Status;
97}
98
99EFI_STATUS
100EFIAPI
101DeviceIoMemRead (
102 IN EFI_DEVICE_IO_PROTOCOL *This,
103 IN EFI_IO_WIDTH Width,
104 IN UINT64 Address,
105 IN UINTN Count,
106 IN OUT VOID *Buffer
107 )
108/*++
109
110Routine Description:
111
112 Perform reading memory mapped I/O space of device.
113
114Arguments:
115
116 This - A pointer to EFI_DEVICE_IO protocol instance.
117 Width - Width of I/O operations.
118 Address - The base address of I/O operations.
119 Count - The number of I/O operations to perform.
120 Bytes moves is Width size * Count, starting at Address.
121 Buffer - The destination buffer to store results.
122
123Returns:
124
125 EFI_SUCCESS - The data was read from the device.
126 EFI_INVALID_PARAMETER - Width is invalid.
127 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
128
129--*/
130{
131 EFI_STATUS Status;
132 DEVICE_IO_PRIVATE_DATA *Private;
133
134 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
135
136 if (Width > MMIO_COPY_UINT64) {
137 return EFI_INVALID_PARAMETER;
138 }
139 if (Width >= MMIO_COPY_UINT8) {
140 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);
141 Status = Private->PciRootBridgeIo->CopyMem (
142 Private->PciRootBridgeIo,
143 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
144 (UINT64)(UINTN) Buffer,
145 Address,
146 Count
147 );
148 } else {
149 Status = Private->PciRootBridgeIo->Mem.Read (
150 Private->PciRootBridgeIo,
151 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
152 Address,
153 Count,
154 Buffer
155 );
156 }
157
158 return Status;
159}
160
161
162
163EFI_STATUS
164EFIAPI
165DeviceIoMemWrite (
166 IN EFI_DEVICE_IO_PROTOCOL *This,
167 IN EFI_IO_WIDTH Width,
168 IN UINT64 Address,
169 IN UINTN Count,
170 IN OUT VOID *Buffer
171 )
172/*++
173
174Routine Description:
175
176 Perform writing memory mapped I/O space of device.
177
178Arguments:
179
180 This - A pointer to EFI_DEVICE_IO protocol instance.
181 Width - Width of I/O operations.
182 Address - The base address of I/O operations.
183 Count - The number of I/O operations to perform.
184 Bytes moves is Width size * Count, starting at Address.
185 Buffer - The source buffer of data to be written.
186
187Returns:
188
189 EFI_SUCCESS - The data was written to the device.
190 EFI_INVALID_PARAMETER - Width is invalid.
191 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
192
193--*/
194{
195 EFI_STATUS Status;
196 DEVICE_IO_PRIVATE_DATA *Private;
197
198 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
199
200 if (Width > MMIO_COPY_UINT64) {
201 return EFI_INVALID_PARAMETER;
202 }
203 if (Width >= MMIO_COPY_UINT8) {
204 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);
205 Status = Private->PciRootBridgeIo->CopyMem (
206 Private->PciRootBridgeIo,
207 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
208 Address,
209 (UINT64)(UINTN) Buffer,
210 Count
211 );
212 } else {
213 Status = Private->PciRootBridgeIo->Mem.Write (
214 Private->PciRootBridgeIo,
215 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
216 Address,
217 Count,
218 Buffer
219 );
220 }
221
222 return Status;
223}
224
225EFI_STATUS
226EFIAPI
227DeviceIoIoRead (
228 IN EFI_DEVICE_IO_PROTOCOL *This,
229 IN EFI_IO_WIDTH Width,
230 IN UINT64 Address,
231 IN UINTN Count,
232 IN OUT VOID *Buffer
233 )
234/*++
235
236Routine Description:
237
238 Perform reading I/O space of device.
239
240Arguments:
241
242 This - A pointer to EFI_DEVICE_IO protocol instance.
243 Width - Width of I/O operations.
244 Address - The base address of I/O operations.
245 Count - The number of I/O operations to perform.
246 Bytes moves is Width size * Count, starting at Address.
247 Buffer - The destination buffer to store results.
248
249Returns:
250
251 EFI_SUCCESS - The data was read from the device.
252 EFI_INVALID_PARAMETER - Width is invalid.
253 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
254
255--*/
256{
257 EFI_STATUS Status;
258 DEVICE_IO_PRIVATE_DATA *Private;
259
260 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
261
262 if (Width >= MMIO_COPY_UINT8) {
263 return EFI_INVALID_PARAMETER;
264 }
265
266 Status = Private->PciRootBridgeIo->Io.Read (
267 Private->PciRootBridgeIo,
268 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
269 Address,
270 Count,
271 Buffer
272 );
273
274 return Status;
275}
276
277EFI_STATUS
278EFIAPI
279DeviceIoIoWrite (
280 IN EFI_DEVICE_IO_PROTOCOL *This,
281 IN EFI_IO_WIDTH Width,
282 IN UINT64 Address,
283 IN UINTN Count,
284 IN OUT VOID *Buffer
285 )
286/*++
287
288Routine Description:
289
290 Perform writing I/O space of device.
291
292Arguments:
293
294 This - A pointer to EFI_DEVICE_IO protocol instance.
295 Width - Width of I/O operations.
296 Address - The base address of I/O operations.
297 Count - The number of I/O operations to perform.
298 Bytes moves is Width size * Count, starting at Address.
299 Buffer - The source buffer of data to be written.
300
301Returns:
302
303 EFI_SUCCESS - The data was written to the device.
304 EFI_INVALID_PARAMETER - Width is invalid.
305 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
306
307--*/
308{
309 EFI_STATUS Status;
310 DEVICE_IO_PRIVATE_DATA *Private;
311
312 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
313
314 if (Width >= MMIO_COPY_UINT8) {
315 return EFI_INVALID_PARAMETER;
316 }
317
318 Status = Private->PciRootBridgeIo->Io.Write (
319 Private->PciRootBridgeIo,
320 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
321 Address,
322 Count,
323 Buffer
324 );
325
326 return Status;
327}
328
329EFI_STATUS
330EFIAPI
331DeviceIoPciRead (
332 IN EFI_DEVICE_IO_PROTOCOL *This,
333 IN EFI_IO_WIDTH Width,
334 IN UINT64 Address,
335 IN UINTN Count,
336 IN OUT VOID *Buffer
337 )
338/*++
339
340Routine Description:
341
342 Perform reading PCI configuration space of device
343
344Arguments:
345
346 This - A pointer to EFI_DEVICE_IO protocol instance.
347 Width - Width of I/O operations.
348 Address - The base address of I/O operations.
349 Count - The number of I/O operations to perform.
350 Bytes moves is Width size * Count, starting at Address.
351 Buffer - The destination buffer to store results.
352
353Returns:
354
355 EFI_SUCCESS - The data was read from the device.
356 EFI_INVALID_PARAMETER - Width is invalid.
357 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
358
359--*/
360{
361 EFI_STATUS Status;
362 DEVICE_IO_PRIVATE_DATA *Private;
363
364 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
365
366 if ((UINT32)Width >= MMIO_COPY_UINT8) {
367 return EFI_INVALID_PARAMETER;
368 }
369
370 Status = Private->PciRootBridgeIo->Pci.Read (
371 Private->PciRootBridgeIo,
372 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
373 Address,
374 Count,
375 Buffer
376 );
377
378 return Status;
379}
380
381EFI_STATUS
382EFIAPI
383DeviceIoPciWrite (
384 IN EFI_DEVICE_IO_PROTOCOL *This,
385 IN EFI_IO_WIDTH Width,
386 IN UINT64 Address,
387 IN UINTN Count,
388 IN OUT VOID *Buffer
389 )
390/*++
391
392Routine Description:
393
394 Perform writing PCI configuration space of device.
395
396Arguments:
397
398 This - A pointer to EFI_DEVICE_IO protocol instance.
399 Width - Width of I/O operations.
400 Address - The base address of I/O operations.
401 Count - The number of I/O operations to perform.
402 Bytes moves is Width size * Count, starting at Address.
403 Buffer - The source buffer of data to be written.
404
405Returns:
406
407 EFI_SUCCESS - The data was written to the device.
408 EFI_INVALID_PARAMETER - Width is invalid.
409 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
410
411--*/
412{
413 EFI_STATUS Status;
414 DEVICE_IO_PRIVATE_DATA *Private;
415
416 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
417
418 if ((UINT32)Width >= MMIO_COPY_UINT8) {
419 return EFI_INVALID_PARAMETER;
420 }
421
422 Status = Private->PciRootBridgeIo->Pci.Write (
423 Private->PciRootBridgeIo,
424 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
425 Address,
426 Count,
427 Buffer
428 );
429
430 return Status;
431}
432
433EFI_DEVICE_PATH_PROTOCOL *
434AppendPciDevicePath (
435 IN DEVICE_IO_PRIVATE_DATA *Private,
436 IN UINT8 Bus,
437 IN UINT8 Device,
438 IN UINT8 Function,
439 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
440 IN OUT UINT16 *BridgePrimaryBus,
441 IN OUT UINT16 *BridgeSubordinateBus
442 )
443/*++
444
445Routine Description:
446
447 Append a PCI device path node to another device path.
448
449Arguments:
450
451 Private - A pointer to DEVICE_IO_PRIVATE_DATA instance.
452 Bus - PCI bus number of the device.
453 Device - PCI device number of the device.
454 Function - PCI function number of the device.
455 DevicePath - Original device path which will be appended a PCI device path node.
456 BridgePrimaryBus - Primary bus number of the bridge.
457 BridgeSubordinateBus - Subordinate bus number of the bridge.
458
459Returns:
460
461 Pointer to the appended PCI device path.
462
463--*/
464{
465 UINT16 ThisBus;
466 UINT8 ThisDevice;
467 UINT8 ThisFunc;
468 UINT64 Address;
469 PCI_TYPE01 PciBridge;
470 PCI_TYPE01 *PciPtr;
471 EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath;
472 PCI_DEVICE_PATH PciNode;
473
474 PciPtr = &PciBridge;
475 for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) {
476 for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) {
477 for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) {
478 Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0);
479 ZeroMem (PciPtr, sizeof (PCI_TYPE01));
480 Private->DeviceIo.Pci.Read (
481 &Private->DeviceIo,
482 IO_UINT32,
483 Address,
484 1,
485 &(PciPtr->Hdr.VendorId)
486 );
487 if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) {
488 break;
489 }
490 if (PciPtr->Hdr.VendorId == 0xffff) {
491 continue;
492 }
493
494 Private->DeviceIo.Pci.Read (
495 &Private->DeviceIo,
496 IO_UINT32,
497 Address,
498 sizeof (PCI_TYPE01) / sizeof (UINT32),
499 PciPtr
500 );
501 if (IS_PCI_BRIDGE (PciPtr)) {
502 if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) {
503
504 PciNode.Header.Type = HARDWARE_DEVICE_PATH;
505 PciNode.Header.SubType = HW_PCI_DP;
506 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
507
508 PciNode.Device = ThisDevice;
509 PciNode.Function = ThisFunc;
510 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);
511
512 *BridgePrimaryBus = PciPtr->Bridge.SecondaryBus;
513 *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;
514 return ReturnDevicePath;
515 }
516 }
517
518 if ((ThisFunc == 0) && ((PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x0)) {
519 //
520 // Skip sub functions, this is not a multi function device
521 //
522 break;
523 }
524 }
525 }
526 }
527
528 ZeroMem (&PciNode, sizeof (PciNode));
529 PciNode.Header.Type = HARDWARE_DEVICE_PATH;
530 PciNode.Header.SubType = HW_PCI_DP;
531 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
532 PciNode.Device = Device;
533 PciNode.Function = Function;
534
535 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);
536
537 *BridgePrimaryBus = 0xffff;
538 *BridgeSubordinateBus = 0xffff;
539 return ReturnDevicePath;
540}
541
542EFI_STATUS
543EFIAPI
544DeviceIoPciDevicePath (
545 IN EFI_DEVICE_IO_PROTOCOL *This,
546 IN UINT64 Address,
547 IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath
548 )
549/*++
550
551Routine Description:
552
553 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.
554
555Arguments:
556
557 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
558 Address - The PCI configuration space address of the device whose Device Path
559 is going to be returned.
560 PciDevicePath - A pointer to the pointer for the EFI Device Path for PciAddress.
561 Memory for the Device Path is allocated from the pool.
562
563Returns:
564
565 EFI_SUCCESS - The PciDevicePath returns a pointer to a valid EFI Device Path.
566 EFI_UNSUPPORTED - The PciAddress does not map to a valid EFI Device Path.
567 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
568
569--*/
570{
571 DEVICE_IO_PRIVATE_DATA *Private;
572 UINT16 PrimaryBus;
573 UINT16 SubordinateBus;
574 UINT8 Bus;
575 UINT8 Device;
576 UINT8 Func;
577
578 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
579
580 Bus = (UINT8) (((UINT32) Address >> 24) & 0xff);
581 Device = (UINT8) (((UINT32) Address >> 16) & 0xff);
582 Func = (UINT8) (((UINT32) Address >> 8) & 0xff);
583
584 if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) {
585 return EFI_UNSUPPORTED;
586 }
587
588 *PciDevicePath = Private->DevicePath;
589 PrimaryBus = Private->PrimaryBus;
590 SubordinateBus = Private->SubordinateBus;
591 do {
592 *PciDevicePath = AppendPciDevicePath (
593 Private,
594 Bus,
595 Device,
596 Func,
597 *PciDevicePath,
598 &PrimaryBus,
599 &SubordinateBus
600 );
601 if (*PciDevicePath == NULL) {
602 return EFI_OUT_OF_RESOURCES;
603 }
604 } while (PrimaryBus != 0xffff);
605
606 return EFI_SUCCESS;
607}
608
609EFI_STATUS
610EFIAPI
611DeviceIoMap (
612 IN EFI_DEVICE_IO_PROTOCOL *This,
613 IN EFI_IO_OPERATION_TYPE Operation,
614 IN EFI_PHYSICAL_ADDRESS *HostAddress,
615 IN OUT UINTN *NumberOfBytes,
616 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
617 OUT VOID **Mapping
618 )
619/*++
620
621Routine Description:
622
623 Provides the device-specific addresses needed to access system memory.
624
625Arguments:
626
627 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
628 Operation - Indicates if the bus master is going to read or write to system memory.
629 HostAddress - The system memory address to map to the device.
630 NumberOfBytes - On input the number of bytes to map. On output the number of bytes
631 that were mapped.
632 DeviceAddress - The resulting map address for the bus master device to use to access the
633 hosts HostAddress.
634 Mapping - A resulting value to pass to Unmap().
635
636Returns:
637
638 EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
639 EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
640 EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common buffer.
641 EFI_DEVICE_ERROR - The system hardware could not map the requested address.
642 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
643
644--*/
645{
646 EFI_STATUS Status;
647 DEVICE_IO_PRIVATE_DATA *Private;
648
649 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
650
651 if ((UINT32)Operation > EfiBusMasterCommonBuffer) {
652 return EFI_INVALID_PARAMETER;
653 }
654
655 if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) {
656 return EFI_UNSUPPORTED;
657 }
658
659 Status = Private->PciRootBridgeIo->Map (
660 Private->PciRootBridgeIo,
661 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
662 (VOID *) (UINTN) (*HostAddress),
663 NumberOfBytes,
664 DeviceAddress,
665 Mapping
666 );
667
668 return Status;
669}
670
671EFI_STATUS
672EFIAPI
673DeviceIoUnmap (
674 IN EFI_DEVICE_IO_PROTOCOL *This,
675 IN VOID *Mapping
676 )
677/*++
678
679Routine Description:
680
681 Completes the Map() operation and releases any corresponding resources.
682
683Arguments:
684
685 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
686 Mapping - The mapping value returned from Map().
687
688Returns:
689
690 EFI_SUCCESS - The range was unmapped.
691 EFI_DEVICE_ERROR - The data was not committed to the target system memory.
692
693--*/
694{
695 EFI_STATUS Status;
696 DEVICE_IO_PRIVATE_DATA *Private;
697
698 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
699
700 Status = Private->PciRootBridgeIo->Unmap (
701 Private->PciRootBridgeIo,
702 Mapping
703 );
704
705 return Status;
706}
707
708EFI_STATUS
709EFIAPI
710DeviceIoAllocateBuffer (
711 IN EFI_DEVICE_IO_PROTOCOL *This,
712 IN EFI_ALLOCATE_TYPE Type,
713 IN EFI_MEMORY_TYPE MemoryType,
714 IN UINTN Pages,
715 IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress
716 )
717/*++
718
719Routine Description:
720
721 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
722
723Arguments:
724
725 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
726 Type - The type allocation to perform.
727 MemoryType - The type of memory to allocate, EfiBootServicesData or
728 EfiRuntimeServicesData.
729 Pages - The number of pages to allocate.
730 PhysicalAddress - A pointer to store the base address of the allocated range.
731
732Returns:
733
734 EFI_SUCCESS - The requested memory pages were allocated.
735 EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
736 EFI_INVALID_PARAMETER - The requested memory type is invalid.
737 EFI_UNSUPPORTED - The requested PhysicalAddress is not supported on
738 this platform.
739
740--*/
741{
742 EFI_STATUS Status;
743 EFI_PHYSICAL_ADDRESS HostAddress;
744
745 HostAddress = *PhysicalAddress;
746
747 if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {
748 return EFI_INVALID_PARAMETER;
749 }
750
751 if ((UINT32)Type >= MaxAllocateType) {
752 return EFI_INVALID_PARAMETER;
753 }
754
755 if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) {
756 return EFI_UNSUPPORTED;
757 }
758
759 if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) {
760 Type = AllocateMaxAddress;
761 HostAddress = MAX_COMMON_BUFFER;
762 }
763
764 Status = gBS->AllocatePages (
765 Type,
766 MemoryType,
767 Pages,
768 &HostAddress
769 );
770 if (EFI_ERROR (Status)) {
771 return Status;
772 }
773
774
775 *PhysicalAddress = HostAddress;
776
777 return EFI_SUCCESS;
778}
779
780EFI_STATUS
781EFIAPI
782DeviceIoFlush (
783 IN EFI_DEVICE_IO_PROTOCOL *This
784 )
785/*++
786
787Routine Description:
788
789 Flushes any posted write data to the device.
790
791Arguments:
792
793 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
794
795Returns:
796
797 EFI_SUCCESS - The buffers were flushed.
798 EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error.
799
800--*/
801{
802 EFI_STATUS Status;
803 DEVICE_IO_PRIVATE_DATA *Private;
804
805 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
806
807 Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo);
808
809 return Status;
810}
811
812EFI_STATUS
813EFIAPI
814DeviceIoFreeBuffer (
815 IN EFI_DEVICE_IO_PROTOCOL *This,
816 IN UINTN Pages,
817 IN EFI_PHYSICAL_ADDRESS HostAddress
818 )
819/*++
820
821Routine Description:
822
823 Frees pages that were allocated with AllocateBuffer().
824
825Arguments:
826
827 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
828 Pages - The number of pages to free.
829 HostAddress - The base address of the range to free.
830
831Returns:
832
833 EFI_SUCCESS - The requested memory pages were freed.
834 EFI_NOT_FOUND - The requested memory pages were not allocated with
835 AllocateBuffer().
836 EFI_INVALID_PARAMETER - HostAddress is not page aligned or Pages is invalid.
837
838--*/
839{
840 if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {
841 return EFI_INVALID_PARAMETER;
842 }
843
844 return gBS->FreePages (HostAddress, Pages);
845}