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