3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Initialization functions for EFI UNDI32 driver
25 #include <Library/BaseLib.h>
30 PXE_SW_UNDI
*pxe_31
= NULL
; // 3.1 entry
31 UNDI32_DEV
*UNDI32DeviceList
[MAX_NIC_INTERFACES
];
32 NII_TABLE
*UndiDataPointer
= NULL
;
44 When address mapping changes to virtual this should make the appropriate
49 (Standard Event handler)
56 // TODO: Context - add argument and description to function comment
62 Pxe31Pointer
= (VOID
*) pxe_31
;
66 (VOID
**) &Pxe31Pointer
70 // UNDI32DeviceList is an array of pointers
72 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
73 UNDI32DeviceList
[Index
]->NIIProtocol_31
.ID
= (UINT64
) (UINTN
) Pxe31Pointer
;
76 (VOID
**) &(UNDI32DeviceList
[Index
])
82 (VOID
**) &(pxe_31
->EntryPoint
)
84 pxe_31
= Pxe31Pointer
;
87 for (Index
= 0; Index
<= PXE_OPCODE_LAST_VALID
; Index
++) {
90 (VOID
**) &api_table
[Index
].api_ptr
105 When EFI is shuting down the boot services, we need to install a
106 configuration table for UNDI to work at runtime!
110 (Standard Event handler)
117 // TODO: Context - add argument and description to function comment
119 InstallConfigTable ();
122 // UNDI Class Driver Global Variables
124 EFI_DRIVER_BINDING_PROTOCOL gUndiDriverBinding
= {
136 UndiDriverSupported (
137 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
138 IN EFI_HANDLE Controller
,
139 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
145 Test to see if this driver supports ControllerHandle. Any ControllerHandle
146 than contains a DevicePath, PciIo protocol, Class code of 2, Vendor ID of 0x8086,
147 and DeviceId of (D100_DEVICE_ID || D102_DEVICE_ID || ICH3_DEVICE_ID_1 ||
148 ICH3_DEVICE_ID_2 || ICH3_DEVICE_ID_3 || ICH3_DEVICE_ID_4 || ICH3_DEVICE_ID_5 ||
149 ICH3_DEVICE_ID_6 || ICH3_DEVICE_ID_7 || ICH3_DEVICE_ID_8) can be supported.
153 This - Protocol instance pointer.
155 Controller - Handle of device to test.
157 RemainingDevicePath - Not used.
161 EFI_SUCCESS - This driver supports this device.
163 other - This driver does not support this device.
168 EFI_PCI_IO_PROTOCOL
*PciIo
;
171 Status
= gBS
->OpenProtocol (
173 &gEfiDevicePathProtocolGuid
,
175 This
->DriverBindingHandle
,
177 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
179 if (EFI_ERROR (Status
)) {
183 Status
= gBS
->OpenProtocol (
185 &gEfiPciIoProtocolGuid
,
187 This
->DriverBindingHandle
,
189 EFI_OPEN_PROTOCOL_BY_DRIVER
191 if (EFI_ERROR (Status
)) {
195 Status
= PciIo
->Pci
.Read (
199 sizeof (PCI_CONFIG_HEADER
),
203 if (!EFI_ERROR (Status
)) {
204 Status
= EFI_UNSUPPORTED
;
206 if (Pci
.Hdr
.ClassCode
[2] == 0x02 && Pci
.Hdr
.VendorId
== PCI_VENDOR_ID_INTEL
) {
207 switch (Pci
.Hdr
.DeviceId
) {
210 case ICH3_DEVICE_ID_1
:
211 case ICH3_DEVICE_ID_2
:
212 case ICH3_DEVICE_ID_3
:
213 case ICH3_DEVICE_ID_4
:
214 case ICH3_DEVICE_ID_5
:
215 case ICH3_DEVICE_ID_6
:
216 case ICH3_DEVICE_ID_7
:
217 case ICH3_DEVICE_ID_8
:
234 Status
= EFI_SUCCESS
;
241 &gEfiPciIoProtocolGuid
,
242 This
->DriverBindingHandle
,
252 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
253 IN EFI_HANDLE Controller
,
254 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
260 Start this driver on Controller by opening PciIo and DevicePath protocol.
261 Initialize PXE structures, create a copy of the Controller Device Path with the
262 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
263 on the newly created Device Path.
267 This - Protocol instance pointer.
269 Controller - Handle of device to work with.
271 RemainingDevicePath - Not used, always produce all possible children.
275 EFI_SUCCESS - This driver is added to Controller.
277 other - This driver does not support this device.
282 EFI_DEVICE_PATH_PROTOCOL
*UndiDevicePath
;
283 PCI_CONFIG_HEADER
*CfgHdr
;
284 UNDI32_DEV
*UNDI32Device
;
286 UINT8
*TmpPxePointer
;
287 EFI_PCI_IO_PROTOCOL
*PciIoFncs
;
290 BOOLEAN PciAttributesSaved
;
292 Status
= gBS
->OpenProtocol (
294 &gEfiPciIoProtocolGuid
,
295 (VOID
**) &PciIoFncs
,
296 This
->DriverBindingHandle
,
298 EFI_OPEN_PROTOCOL_BY_DRIVER
301 if (EFI_ERROR (Status
)) {
305 Status
= gBS
->OpenProtocol (
307 &gEfiDevicePathProtocolGuid
,
308 (VOID
**) &UndiDevicePath
,
309 This
->DriverBindingHandle
,
311 EFI_OPEN_PROTOCOL_BY_DRIVER
314 if (EFI_ERROR (Status
)) {
317 &gEfiPciIoProtocolGuid
,
318 This
->DriverBindingHandle
,
325 PciAttributesSaved
= FALSE
;
327 Status
= gBS
->AllocatePool (
328 EfiRuntimeServicesData
,
330 (VOID
**) &UNDI32Device
333 if (EFI_ERROR (Status
)) {
337 ZeroMem ((CHAR8
*) UNDI32Device
, sizeof (UNDI32_DEV
));
340 // Get original PCI attributes
342 Status
= PciIoFncs
->Attributes (
344 EfiPciIoAttributeOperationGet
,
346 &UNDI32Device
->NicInfo
.OriginalPciAttributes
349 if (EFI_ERROR (Status
)) {
350 goto UndiErrorDeleteDevice
;
352 PciAttributesSaved
= TRUE
;
355 // allocate and initialize both (old and new) the !pxe structures here,
356 // there should only be one copy of each of these structure for any number
357 // of NICs this undi supports. Also, these structures need to be on a
358 // paragraph boundary as per the spec. so, while allocating space for these,
359 // make sure that there is space for 2 !pxe structures (old and new) and a
360 // 32 bytes padding for alignment adjustment (in case)
362 TmpPxePointer
= NULL
;
363 if (pxe_31
== NULL
) {
364 Status
= gBS
->AllocatePool (
365 EfiRuntimeServicesData
,
366 (sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32),
367 (VOID
**) &TmpPxePointer
370 if (EFI_ERROR (Status
)) {
371 goto UndiErrorDeleteDevice
;
376 sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32
379 // check for paragraph alignment here, assuming that the pointer is
380 // already 8 byte aligned.
382 if (((UINTN
) TmpPxePointer
& 0x0F) != 0) {
383 pxe_31
= (PXE_SW_UNDI
*) ((UINTN
) (TmpPxePointer
+ 8));
385 pxe_31
= (PXE_SW_UNDI
*) TmpPxePointer
;
388 PxeStructInit (pxe_31
);
391 UNDI32Device
->NIIProtocol_31
.ID
= (UINT64
) (UINTN
) (pxe_31
);
393 Status
= PciIoFncs
->Attributes (
395 EfiPciIoAttributeOperationSupported
,
399 if (!EFI_ERROR (Status
)) {
400 Supports
&= EFI_PCI_DEVICE_ENABLE
;
401 Status
= PciIoFncs
->Attributes (
403 EfiPciIoAttributeOperationEnable
,
409 // Read all the registers from device's PCI Configuration space
411 Status
= PciIoFncs
->Pci
.Read (
416 &UNDI32Device
->NicInfo
.Config
419 CfgHdr
= (PCI_CONFIG_HEADER
*) &(UNDI32Device
->NicInfo
.Config
[0]);
422 // make sure that this device is a PCI bus master
425 NewCommand
= (UINT16
) (CfgHdr
->Command
| PCI_COMMAND_MASTER
| PCI_COMMAND_IO
);
426 if (CfgHdr
->Command
!= NewCommand
) {
427 PciIoFncs
->Pci
.Write (
434 CfgHdr
->Command
= NewCommand
;
438 // make sure that the latency timer is at least 32
440 if (CfgHdr
->LatencyTimer
< 32) {
441 CfgHdr
->LatencyTimer
= 32;
442 PciIoFncs
->Pci
.Write (
447 &CfgHdr
->LatencyTimer
451 // the IfNum index for the current interface will be the total number
452 // of interfaces initialized so far
454 UNDI32Device
->NIIProtocol_31
.IfNum
= pxe_31
->IFcnt
;
456 PxeUpdate (&UNDI32Device
->NicInfo
, pxe_31
);
458 UNDI32Device
->NicInfo
.Io_Function
= PciIoFncs
;
459 UNDI32DeviceList
[UNDI32Device
->NIIProtocol_31
.IfNum
] = UNDI32Device
;
460 UNDI32Device
->Undi32BaseDevPath
= UndiDevicePath
;
462 Status
= AppendMac2DevPath (
463 &UNDI32Device
->Undi32DevPath
,
464 UNDI32Device
->Undi32BaseDevPath
,
465 &UNDI32Device
->NicInfo
469 goto UndiErrorDeletePxe
;
472 UNDI32Device
->Signature
= UNDI_DEV_SIGNATURE
;
474 UNDI32Device
->NIIProtocol_31
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31
;
475 UNDI32Device
->NIIProtocol_31
.Type
= EfiNetworkInterfaceUndi
;
476 UNDI32Device
->NIIProtocol_31
.MajorVer
= PXE_ROMID_MAJORVER
;
477 UNDI32Device
->NIIProtocol_31
.MinorVer
= PXE_ROMID_MINORVER_31
;
478 UNDI32Device
->NIIProtocol_31
.ImageSize
= 0;
479 UNDI32Device
->NIIProtocol_31
.ImageAddr
= 0;
480 UNDI32Device
->NIIProtocol_31
.Ipv6Supported
= FALSE
;
482 UNDI32Device
->NIIProtocol_31
.StringId
[0] = 'U';
483 UNDI32Device
->NIIProtocol_31
.StringId
[1] = 'N';
484 UNDI32Device
->NIIProtocol_31
.StringId
[2] = 'D';
485 UNDI32Device
->NIIProtocol_31
.StringId
[3] = 'I';
487 UNDI32Device
->DeviceHandle
= NULL
;
490 // install both the 3.0 and 3.1 NII protocols.
492 Status
= gBS
->InstallMultipleProtocolInterfaces (
493 &UNDI32Device
->DeviceHandle
,
494 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
495 &UNDI32Device
->NIIProtocol_31
,
496 &gEfiDevicePathProtocolGuid
,
497 UNDI32Device
->Undi32DevPath
,
501 if (EFI_ERROR (Status
)) {
502 goto UndiErrorDeleteDevicePath
;
506 // if the table exists, free it and alloc again, or alloc it directly
508 if (UndiDataPointer
!= NULL
) {
509 Status
= gBS
->FreePool(UndiDataPointer
);
511 if (EFI_ERROR (Status
)) {
512 goto UndiErrorDeleteDevicePath
;
515 Len
= (pxe_31
->IFcnt
* sizeof (NII_ENTRY
)) + sizeof (UndiDataPointer
);
516 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, Len
, (VOID
**) &UndiDataPointer
);
518 if (EFI_ERROR (Status
)) {
519 goto UndiErrorAllocDataPointer
;
523 // Open For Child Device
525 Status
= gBS
->OpenProtocol (
527 &gEfiPciIoProtocolGuid
,
528 (VOID
**) &PciIoFncs
,
529 This
->DriverBindingHandle
,
530 UNDI32Device
->DeviceHandle
,
531 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
535 UndiErrorAllocDataPointer
:
536 gBS
->UninstallMultipleProtocolInterfaces (
537 &UNDI32Device
->DeviceHandle
,
538 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
539 &UNDI32Device
->NIIProtocol_31
,
540 &gEfiDevicePathProtocolGuid
,
541 UNDI32Device
->Undi32DevPath
,
545 UndiErrorDeleteDevicePath
:
546 UNDI32DeviceList
[UNDI32Device
->NIIProtocol_31
.IfNum
] = NULL
;
547 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
550 PxeUpdate (NULL
, pxe_31
);
551 if (TmpPxePointer
!= NULL
) {
552 gBS
->FreePool (TmpPxePointer
);
556 UndiErrorDeleteDevice
:
557 if (PciAttributesSaved
== TRUE
) {
559 // Restore original PCI attributes
561 PciIoFncs
->Attributes (
563 EfiPciIoAttributeOperationSet
,
564 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
569 gBS
->FreePool (UNDI32Device
);
574 &gEfiDevicePathProtocolGuid
,
575 This
->DriverBindingHandle
,
581 &gEfiPciIoProtocolGuid
,
582 This
->DriverBindingHandle
,
592 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
593 IN EFI_HANDLE Controller
,
594 IN UINTN NumberOfChildren
,
595 IN EFI_HANDLE
*ChildHandleBuffer
600 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
601 closing the DevicePath and PciIo protocols on Controller.
604 This - Protocol instance pointer.
605 Controller - Handle of device to stop driver on.
606 NumberOfChildren - How many children need to be stopped.
607 ChildHandleBuffer - Not used.
610 EFI_SUCCESS - This driver is removed Controller.
611 other - This driver was not removed from this device.
614 // TODO: EFI_DEVICE_ERROR - add return value to function comment
617 BOOLEAN AllChildrenStopped
;
619 UNDI32_DEV
*UNDI32Device
;
620 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NIIProtocol
;
621 EFI_PCI_IO_PROTOCOL
*PciIo
;
624 // Complete all outstanding transactions to Controller.
625 // Don't allow any new transaction to Controller to be started.
627 if (NumberOfChildren
== 0) {
630 // Close the bus driver
632 Status
= gBS
->CloseProtocol (
634 &gEfiDevicePathProtocolGuid
,
635 This
->DriverBindingHandle
,
639 Status
= gBS
->CloseProtocol (
641 &gEfiPciIoProtocolGuid
,
642 This
->DriverBindingHandle
,
649 AllChildrenStopped
= TRUE
;
651 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
653 Status
= gBS
->OpenProtocol (
654 ChildHandleBuffer
[Index
],
655 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
656 (VOID
**) &NIIProtocol
,
657 This
->DriverBindingHandle
,
659 EFI_OPEN_PROTOCOL_GET_PROTOCOL
661 if (!EFI_ERROR (Status
)) {
663 UNDI32Device
= UNDI_DEV_FROM_THIS (NIIProtocol
);
666 // Restore original PCI attributes
668 Status
= UNDI32Device
->NicInfo
.Io_Function
->Attributes (
669 UNDI32Device
->NicInfo
.Io_Function
,
670 EfiPciIoAttributeOperationSet
,
671 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
674 ASSERT_EFI_ERROR (Status
);
676 Status
= gBS
->CloseProtocol (
678 &gEfiPciIoProtocolGuid
,
679 This
->DriverBindingHandle
,
680 ChildHandleBuffer
[Index
]
683 Status
= gBS
->UninstallMultipleProtocolInterfaces (
684 ChildHandleBuffer
[Index
],
685 &gEfiDevicePathProtocolGuid
,
686 UNDI32Device
->Undi32DevPath
,
687 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
688 &UNDI32Device
->NIIProtocol_31
,
692 if (EFI_ERROR (Status
)) {
695 &gEfiPciIoProtocolGuid
,
697 This
->DriverBindingHandle
,
698 ChildHandleBuffer
[Index
],
699 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
702 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
703 gBS
->FreePool (UNDI32Device
);
707 if (EFI_ERROR (Status
)) {
708 AllChildrenStopped
= FALSE
;
712 if (!AllChildrenStopped
) {
713 return EFI_DEVICE_ERROR
;
723 IN UINTN MicroSeconds
729 Use the EFI boot services to produce a pause. This is also the routine which
730 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can
735 UnqId - Runtime O/S routine might use this, this temp routine does not use it
737 MicroSeconds - Determines the length of pause.
745 gBS
->Stall ((UINT32
) MicroSeconds
);
760 Use the PCI IO abstraction to issue memory or I/O reads and writes. This is also the routine which
761 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.
765 UnqId - Runtime O/S routine may use this field, this temp routine does not.
767 ReadWrite - Determine if it is an I/O or Memory Read/Write Operation.
769 Len - Determines the width of the data operation.
771 Port - What port to Read/Write from.
773 BuffAddr - Address to read to or write from.
781 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
782 NIC_DATA_INSTANCE
*AdapterInfo
;
784 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 0;
785 AdapterInfo
= (NIC_DATA_INSTANCE
*) (UINTN
) UnqId
;
788 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 1;
792 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 2;
796 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 3;
802 AdapterInfo
->Io_Function
->Io
.Read (
803 AdapterInfo
->Io_Function
,
808 (VOID
*) (UINTN
) (BuffAddr
)
813 AdapterInfo
->Io_Function
->Io
.Write (
814 AdapterInfo
->Io_Function
,
819 (VOID
*) (UINTN
) (BuffAddr
)
824 AdapterInfo
->Io_Function
->Mem
.Read (
825 AdapterInfo
->Io_Function
,
830 (VOID
*) (UINTN
) (BuffAddr
)
835 AdapterInfo
->Io_Function
->Mem
.Write (
836 AdapterInfo
->Io_Function
,
841 (VOID
*) (UINTN
) (BuffAddr
)
851 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevPtr
,
852 IN EFI_DEVICE_PATH_PROTOCOL
*BaseDevPtr
,
853 IN NIC_DATA_INSTANCE
*AdapterInfo
859 Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space
860 for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)
861 and an added MAC node.
865 DevPtr - Pointer which will point to the newly created device path with the MAC node attached.
867 BaseDevPtr - Pointer to the device path which the UNDI device driver is latching on to.
869 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
873 EFI_SUCCESS - A MAC address was successfully appended to the Base Device Path.
875 other - Not enough resources available to create new Device Path node.
879 EFI_MAC_ADDRESS MACAddress
;
880 PCI_CONFIG_HEADER
*CfgHdr
;
885 MAC_ADDR_DEVICE_PATH MacAddrNode
;
886 EFI_DEVICE_PATH_PROTOCOL
*EndNode
;
893 // set the environment ready (similar to UNDI_Start call) so that we can
894 // execute the other UNDI_ calls to get the mac address
895 // we are using undi 3.1 style
897 AdapterInfo
->Delay
= TmpDelay
;
898 AdapterInfo
->Virt2Phys
= (VOID
*) 0;
899 AdapterInfo
->Block
= (VOID
*) 0;
900 AdapterInfo
->Map_Mem
= (VOID
*) 0;
901 AdapterInfo
->UnMap_Mem
= (VOID
*) 0;
902 AdapterInfo
->Sync_Mem
= (VOID
*) 0;
903 AdapterInfo
->Mem_Io
= TmpMemIo
;
905 // these tmp call-backs follow 3.1 undi style
906 // i.e. they have the unique_id parameter.
908 AdapterInfo
->VersionFlag
= 0x31;
909 AdapterInfo
->Unique_ID
= (UINT64
) (UINTN
) AdapterInfo
;
914 CfgHdr
= (PCI_CONFIG_HEADER
*) &(AdapterInfo
->Config
[0]);
915 AdapterInfo
->ioaddr
= 0;
916 AdapterInfo
->RevID
= CfgHdr
->RevID
;
918 AddrLen
= E100bGetEepromAddrLen (AdapterInfo
);
920 for (Index
= 0, Index2
= 0; Index
< 3; Index
++) {
921 Val
= E100bReadEeprom (AdapterInfo
, Index
, AddrLen
);
922 MACAddress
.Addr
[Index2
++] = (UINT8
) Val
;
923 MACAddress
.Addr
[Index2
++] = (UINT8
) (Val
>> 8);
926 SetMem (MACAddress
.Addr
+ Index2
, sizeof (EFI_MAC_ADDRESS
) - Index2
, 0);
927 //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
928 // MACAddress.Addr[Index2] = 0;
933 AdapterInfo
->Delay
= (VOID
*) 0;
934 AdapterInfo
->Mem_Io
= (VOID
*) 0;
937 // fill the mac address node first
939 ZeroMem ((CHAR8
*) &MacAddrNode
, sizeof MacAddrNode
);
941 (CHAR8
*) &MacAddrNode
.MacAddress
,
942 (CHAR8
*) &MACAddress
,
943 sizeof (EFI_MAC_ADDRESS
)
946 MacAddrNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
947 MacAddrNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
948 MacAddrNode
.Header
.Length
[0] = sizeof (MacAddrNode
);
949 MacAddrNode
.Header
.Length
[1] = 0;
952 // find the size of the base dev path.
954 EndNode
= BaseDevPtr
;
956 while (!IsDevicePathEnd (EndNode
)) {
957 EndNode
= NextDevicePathNode (EndNode
);
960 BasePathLen
= (UINT16
) ((UINTN
) (EndNode
) - (UINTN
) (BaseDevPtr
));
963 // create space for full dev path
965 TotalPathLen
= (UINT16
) (BasePathLen
+ sizeof (MacAddrNode
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
967 Status
= gBS
->AllocatePool (
968 EfiRuntimeServicesData
,
973 if (Status
!= EFI_SUCCESS
) {
977 // copy the base path, mac addr and end_dev_path nodes
979 *DevPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) DevicePtr
;
980 CopyMem (DevicePtr
, (CHAR8
*) BaseDevPtr
, BasePathLen
);
981 DevicePtr
+= BasePathLen
;
982 CopyMem (DevicePtr
, (CHAR8
*) &MacAddrNode
, sizeof (MacAddrNode
));
983 DevicePtr
+= sizeof (MacAddrNode
);
984 CopyMem (DevicePtr
, (CHAR8
*) EndNode
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
997 Install a GUID/Pointer pair into the system's configuration table.
1005 EFI_SUCCESS - Install a GUID/Pointer pair into the system's configuration table.
1007 other - Did not successfully install the GUID/Pointer pair into the configuration table.
1010 // TODO: VOID - add argument and description to function comment
1013 EFI_CONFIGURATION_TABLE
*CfgPtr
;
1016 NII_TABLE
*UndiData
;
1018 if (pxe_31
== NULL
) {
1022 if(UndiDataPointer
== NULL
) {
1026 UndiData
= (NII_TABLE
*)UndiDataPointer
;
1028 UndiData
->NumEntries
= pxe_31
->IFcnt
;
1029 UndiData
->NextLink
= NULL
;
1031 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
1032 UndiData
->NiiEntry
[Index
].InterfacePointer
= &UNDI32DeviceList
[Index
]->NIIProtocol_31
;
1033 UndiData
->NiiEntry
[Index
].DevicePathPointer
= UNDI32DeviceList
[Index
]->Undi32DevPath
;
1037 // see if there is an entry in the config table already
1039 CfgPtr
= gST
->ConfigurationTable
;
1041 for (Index
= 0; Index
< gST
->NumberOfTableEntries
; Index
++) {
1042 Status
= CompareGuid (
1043 &CfgPtr
->VendorGuid
,
1044 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
1046 if (Status
!= EFI_SUCCESS
) {
1053 if (Index
< gST
->NumberOfTableEntries
) {
1054 TmpData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
1057 // go to the last link
1059 while (TmpData
->NextLink
!= NULL
) {
1060 TmpData
= TmpData
->NextLink
;
1063 TmpData
->NextLink
= UndiData
;
1068 UndiData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
1072 // create an entry in the configuration table for our GUID
1074 Status
= gBS
->InstallConfigurationTable (
1075 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1083 Install driver binding protocol of UNDI.
1085 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1086 @param[in] SystemTable A pointer to the EFI System Table.
1088 @retval EFI_SUCCESS The entry point is executed successfully.
1089 @retval other Some error occurs when executing this entry point.
1095 IN EFI_HANDLE ImageHandle
,
1096 IN EFI_SYSTEM_TABLE
*SystemTable
1102 Status
= EfiLibInstallDriverBinding (
1105 &gUndiDriverBinding
,
1108 ASSERT_EFI_ERROR (Status
);
1110 Status
= gBS
->CreateEvent (
1111 EVT_SIGNAL_EXIT_BOOT_SERVICES
,
1117 ASSERT_EFI_ERROR (Status
);
1119 Status
= gBS
->CreateEvent (
1120 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
1126 ASSERT_EFI_ERROR (Status
);