3 Copyright (c) 2006, 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
29 PXE_SW_UNDI
*pxe
= 0; // 3.0 entry point
30 PXE_SW_UNDI
*pxe_31
= 0; // 3.1 entry
31 UNDI32_DEV
*UNDI32DeviceList
[MAX_NIC_INTERFACES
];
33 NII_TABLE
*UnidiDataPointer
=NULL
;
45 When address mapping changes to virtual this should make the appropriate
50 (Standard Event handler)
57 // TODO: Context - add argument and description to function comment
63 Pxe31Pointer
= (VOID
*) pxe_31
;
67 (VOID
**) &Pxe31Pointer
71 // UNDI32DeviceList is an array of pointers
73 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
74 UNDI32DeviceList
[Index
]->NIIProtocol_31
.ID
= (UINT64
) (UINTN
) Pxe31Pointer
;
77 (VOID
**) &(UNDI32DeviceList
[Index
])
83 (VOID
**) &(pxe_31
->EntryPoint
)
85 pxe_31
= Pxe31Pointer
;
88 for (Index
= 0; Index
<= PXE_OPCODE_LAST_VALID
; Index
++) {
91 (VOID
**) &api_table
[Index
].api_ptr
106 When EFI is shuting down the boot services, we need to install a
107 configuration table for UNDI to work at runtime!
111 (Standard Event handler)
118 // TODO: Context - add argument and description to function comment
120 InstallConfigTable ();
123 // UNDI Class Driver Global Variables
125 EFI_DRIVER_BINDING_PROTOCOL gUndiDriverBinding
= {
137 UndiDriverSupported (
138 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
139 IN EFI_HANDLE Controller
,
140 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
146 Test to see if this driver supports ControllerHandle. Any ControllerHandle
147 than contains a DevicePath, PciIo protocol, Class code of 2, Vendor ID of 0x8086,
148 and DeviceId of (D100_DEVICE_ID || D102_DEVICE_ID || ICH3_DEVICE_ID_1 ||
149 ICH3_DEVICE_ID_2 || ICH3_DEVICE_ID_3 || ICH3_DEVICE_ID_4 || ICH3_DEVICE_ID_5 ||
150 ICH3_DEVICE_ID_6 || ICH3_DEVICE_ID_7 || ICH3_DEVICE_ID_8) can be supported.
154 This - Protocol instance pointer.
156 Controller - Handle of device to test.
158 RemainingDevicePath - Not used.
162 EFI_SUCCESS - This driver supports this device.
164 other - This driver does not support this device.
169 EFI_PCI_IO_PROTOCOL
*PciIo
;
172 Status
= gBS
->OpenProtocol (
174 &gEfiDevicePathProtocolGuid
,
176 This
->DriverBindingHandle
,
178 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
180 if (EFI_ERROR (Status
)) {
184 Status
= gBS
->OpenProtocol (
186 &gEfiPciIoProtocolGuid
,
188 This
->DriverBindingHandle
,
190 EFI_OPEN_PROTOCOL_BY_DRIVER
192 if (EFI_ERROR (Status
)) {
196 Status
= PciIo
->Pci
.Read (
200 sizeof (PCI_CONFIG_HEADER
),
204 if (!EFI_ERROR (Status
)) {
205 Status
= EFI_UNSUPPORTED
;
207 if (Pci
.Hdr
.ClassCode
[2] == 0x02 && Pci
.Hdr
.VendorId
== PCI_VENDOR_ID_INTEL
) {
208 switch (Pci
.Hdr
.DeviceId
) {
211 case ICH3_DEVICE_ID_1
:
212 case ICH3_DEVICE_ID_2
:
213 case ICH3_DEVICE_ID_3
:
214 case ICH3_DEVICE_ID_4
:
215 case ICH3_DEVICE_ID_5
:
216 case ICH3_DEVICE_ID_6
:
217 case ICH3_DEVICE_ID_7
:
218 case ICH3_DEVICE_ID_8
:
235 Status
= EFI_SUCCESS
;
242 &gEfiPciIoProtocolGuid
,
243 This
->DriverBindingHandle
,
253 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
254 IN EFI_HANDLE Controller
,
255 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
261 Start this driver on Controller by opening PciIo and DevicePath protocol.
262 Initialize PXE structures, create a copy of the Controller Device Path with the
263 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
264 on the newly created Device Path.
268 This - Protocol instance pointer.
270 Controller - Handle of device to work with.
272 RemainingDevicePath - Not used, always produce all possible children.
276 EFI_SUCCESS - This driver is added to Controller.
278 other - This driver does not support this device.
283 EFI_DEVICE_PATH_PROTOCOL
*UndiDevicePath
;
284 PCI_CONFIG_HEADER
*CfgHdr
;
285 UNDI32_DEV
*UNDI32Device
;
287 UINT8
*TmpPxePointer
;
288 EFI_PCI_IO_PROTOCOL
*PciIoFncs
;
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 Status
= gBS
->AllocatePool (
326 EfiRuntimeServicesData
,
328 (VOID
**) &UNDI32Device
331 if (EFI_ERROR (Status
)) {
335 ZeroMem ((CHAR8
*) UNDI32Device
, sizeof (UNDI32_DEV
));
338 // allocate and initialize both (old and new) the !pxe structures here,
339 // there should only be one copy of each of these structure for any number
340 // of NICs this undi supports. Also, these structures need to be on a
341 // paragraph boundary as per the spec. so, while allocating space for these,
342 // make sure that there is space for 2 !pxe structures (old and new) and a
343 // 32 bytes padding for alignment adjustment (in case)
345 TmpPxePointer
= NULL
;
346 if (pxe_31
== NULL
) {
347 Status
= gBS
->AllocatePool (
348 EfiRuntimeServicesData
,
349 (sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32),
350 (VOID
**) &TmpPxePointer
353 if (EFI_ERROR (Status
)) {
354 goto UndiErrorDeleteDevice
;
359 sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32
362 // check for paragraph alignment here, assuming that the pointer is
363 // already 8 byte aligned.
365 if (((UINTN
) TmpPxePointer
& 0x0F) != 0) {
366 pxe_31
= (PXE_SW_UNDI
*) ((UINTN
) (TmpPxePointer
+ 8));
368 pxe_31
= (PXE_SW_UNDI
*) TmpPxePointer
;
371 // assuming that the sizeof pxe_31 is a 16 byte multiple
373 pxe
= (PXE_SW_UNDI
*) ((CHAR8
*) (pxe_31
) + sizeof (PXE_SW_UNDI
));
375 PxeStructInit (pxe
, 0x30);
376 PxeStructInit (pxe_31
, 0x31);
379 UNDI32Device
->NIIProtocol
.ID
= (UINT64
) (UINTN
) (pxe
);
380 UNDI32Device
->NIIProtocol_31
.ID
= (UINT64
) (UINTN
) (pxe_31
);
382 Status
= PciIoFncs
->Attributes (
384 EfiPciIoAttributeOperationSupported
,
388 if (!EFI_ERROR (Status
)) {
389 Supports
&= EFI_PCI_DEVICE_ENABLE
;
390 Status
= PciIoFncs
->Attributes (
392 EfiPciIoAttributeOperationEnable
,
398 // Read all the registers from device's PCI Configuration space
400 Status
= PciIoFncs
->Pci
.Read (
405 &UNDI32Device
->NicInfo
.Config
408 CfgHdr
= (PCI_CONFIG_HEADER
*) &(UNDI32Device
->NicInfo
.Config
[0]);
411 // make sure that this device is a PCI bus master
414 NewCommand
= (UINT16
) (CfgHdr
->Command
| PCI_COMMAND_MASTER
| PCI_COMMAND_IO
);
415 if (CfgHdr
->Command
!= NewCommand
) {
416 PciIoFncs
->Pci
.Write (
423 CfgHdr
->Command
= NewCommand
;
427 // make sure that the latency timer is at least 32
429 if (CfgHdr
->LatencyTimer
< 32) {
430 CfgHdr
->LatencyTimer
= 32;
431 PciIoFncs
->Pci
.Write (
436 &CfgHdr
->LatencyTimer
440 // the IfNum index for the current interface will be the total number
441 // of interfaces initialized so far
443 UNDI32Device
->NIIProtocol
.IfNum
= pxe
->IFcnt
;
444 UNDI32Device
->NIIProtocol_31
.IfNum
= pxe_31
->IFcnt
;
446 PxeUpdate (&UNDI32Device
->NicInfo
, pxe
);
447 PxeUpdate (&UNDI32Device
->NicInfo
, pxe_31
);
449 UNDI32Device
->NicInfo
.Io_Function
= PciIoFncs
;
450 UNDI32DeviceList
[UNDI32Device
->NIIProtocol
.IfNum
] = UNDI32Device
;
451 UNDI32Device
->Undi32BaseDevPath
= UndiDevicePath
;
453 Status
= AppendMac2DevPath (
454 &UNDI32Device
->Undi32DevPath
,
455 UNDI32Device
->Undi32BaseDevPath
,
456 &UNDI32Device
->NicInfo
460 goto UndiErrorDeletePxe
;
463 UNDI32Device
->Signature
= UNDI_DEV_SIGNATURE
;
465 UNDI32Device
->NIIProtocol
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION
;
466 UNDI32Device
->NIIProtocol
.Type
= EfiNetworkInterfaceUndi
;
467 UNDI32Device
->NIIProtocol
.MajorVer
= PXE_ROMID_MAJORVER
;
468 UNDI32Device
->NIIProtocol
.MinorVer
= PXE_ROMID_MINORVER
;
469 UNDI32Device
->NIIProtocol
.ImageSize
= 0;
470 UNDI32Device
->NIIProtocol
.ImageAddr
= 0;
471 UNDI32Device
->NIIProtocol
.Ipv6Supported
= FALSE
;
473 UNDI32Device
->NIIProtocol
.StringId
[0] = 'U';
474 UNDI32Device
->NIIProtocol
.StringId
[1] = 'N';
475 UNDI32Device
->NIIProtocol
.StringId
[2] = 'D';
476 UNDI32Device
->NIIProtocol
.StringId
[3] = 'I';
478 UNDI32Device
->NIIProtocol_31
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31
;
479 UNDI32Device
->NIIProtocol_31
.Type
= EfiNetworkInterfaceUndi
;
480 UNDI32Device
->NIIProtocol_31
.MajorVer
= PXE_ROMID_MAJORVER
;
481 UNDI32Device
->NIIProtocol_31
.MinorVer
= PXE_ROMID_MINORVER_31
;
482 UNDI32Device
->NIIProtocol_31
.ImageSize
= 0;
483 UNDI32Device
->NIIProtocol_31
.ImageAddr
= 0;
484 UNDI32Device
->NIIProtocol_31
.Ipv6Supported
= FALSE
;
486 UNDI32Device
->NIIProtocol_31
.StringId
[0] = 'U';
487 UNDI32Device
->NIIProtocol_31
.StringId
[1] = 'N';
488 UNDI32Device
->NIIProtocol_31
.StringId
[2] = 'D';
489 UNDI32Device
->NIIProtocol_31
.StringId
[3] = 'I';
491 UNDI32Device
->DeviceHandle
= NULL
;
494 // install both the 3.0 and 3.1 NII protocols.
496 Status
= gBS
->InstallMultipleProtocolInterfaces (
497 &UNDI32Device
->DeviceHandle
,
498 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
499 &UNDI32Device
->NIIProtocol_31
,
500 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
501 &UNDI32Device
->NIIProtocol
,
502 &gEfiDevicePathProtocolGuid
,
503 UNDI32Device
->Undi32DevPath
,
507 if (EFI_ERROR (Status
)) {
508 goto UndiErrorDeleteDevicePath
;
512 // if the table exists, free it and alloc again, or alloc it directly
514 if (UnidiDataPointer
!= NULL
) {
515 Status
= gBS
->FreePool(UnidiDataPointer
);
517 if (EFI_ERROR (Status
)) {
518 goto UndiErrorDeleteDevicePath
;
521 Len
= (pxe_31
->IFcnt
* sizeof (NII_ENTRY
)) + sizeof (UnidiDataPointer
);
522 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, Len
, (VOID
**) &UnidiDataPointer
);
524 if (EFI_ERROR (Status
)) {
525 goto UndiErrorAllocDataPointer
;
529 // Open For Child Device
531 Status
= gBS
->OpenProtocol (
533 &gEfiPciIoProtocolGuid
,
534 (VOID
**) &PciIoFncs
,
535 This
->DriverBindingHandle
,
536 UNDI32Device
->DeviceHandle
,
537 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
541 UndiErrorAllocDataPointer
:
542 gBS
->UninstallMultipleProtocolInterfaces (
543 &UNDI32Device
->DeviceHandle
,
544 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
545 &UNDI32Device
->NIIProtocol_31
,
546 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
547 &UNDI32Device
->NIIProtocol
,
548 &gEfiDevicePathProtocolGuid
,
549 UNDI32Device
->Undi32DevPath
,
553 UndiErrorDeleteDevicePath
:
554 UNDI32DeviceList
[UNDI32Device
->NIIProtocol
.IfNum
] = NULL
;
555 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
558 PxeUpdate (NULL
, pxe
);
559 PxeUpdate (NULL
, pxe_31
);
560 if (TmpPxePointer
!= NULL
) {
561 gBS
->FreePool (TmpPxePointer
);
565 UndiErrorDeleteDevice
:
566 gBS
->FreePool (UNDI32Device
);
571 &gEfiDevicePathProtocolGuid
,
572 This
->DriverBindingHandle
,
578 &gEfiPciIoProtocolGuid
,
579 This
->DriverBindingHandle
,
589 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
590 IN EFI_HANDLE Controller
,
591 IN UINTN NumberOfChildren
,
592 IN EFI_HANDLE
*ChildHandleBuffer
597 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
598 closing the DevicePath and PciIo protocols on Controller.
601 This - Protocol instance pointer.
602 Controller - Handle of device to stop driver on.
603 NumberOfChildren - How many children need to be stopped.
604 ChildHandleBuffer - Not used.
607 EFI_SUCCESS - This driver is removed Controller.
608 other - This driver was not removed from this device.
611 // TODO: EFI_DEVICE_ERROR - add return value to function comment
614 BOOLEAN AllChildrenStopped
;
616 UNDI32_DEV
*UNDI32Device
;
617 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NIIProtocol
;
618 EFI_PCI_IO_PROTOCOL
*PciIo
;
621 // Complete all outstanding transactions to Controller.
622 // Don't allow any new transaction to Controller to be started.
624 if (NumberOfChildren
== 0) {
627 // Close the bus driver
629 Status
= gBS
->CloseProtocol (
631 &gEfiDevicePathProtocolGuid
,
632 This
->DriverBindingHandle
,
636 Status
= gBS
->CloseProtocol (
638 &gEfiPciIoProtocolGuid
,
639 This
->DriverBindingHandle
,
646 AllChildrenStopped
= TRUE
;
648 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
650 Status
= gBS
->OpenProtocol (
651 ChildHandleBuffer
[Index
],
652 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
653 (VOID
**) &NIIProtocol
,
654 This
->DriverBindingHandle
,
656 EFI_OPEN_PROTOCOL_GET_PROTOCOL
658 if (!EFI_ERROR (Status
)) {
660 UNDI32Device
= UNDI_DEV_FROM_THIS (NIIProtocol
);
662 Status
= gBS
->CloseProtocol (
664 &gEfiPciIoProtocolGuid
,
665 This
->DriverBindingHandle
,
666 ChildHandleBuffer
[Index
]
669 Status
= gBS
->UninstallMultipleProtocolInterfaces (
670 ChildHandleBuffer
[Index
],
671 &gEfiDevicePathProtocolGuid
,
672 UNDI32Device
->Undi32DevPath
,
673 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
674 &UNDI32Device
->NIIProtocol_31
,
675 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
676 &UNDI32Device
->NIIProtocol
,
680 if (EFI_ERROR (Status
)) {
683 &gEfiPciIoProtocolGuid
,
685 This
->DriverBindingHandle
,
686 ChildHandleBuffer
[Index
],
687 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
690 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
691 gBS
->FreePool (UNDI32Device
);
695 if (EFI_ERROR (Status
)) {
696 AllChildrenStopped
= FALSE
;
700 if (!AllChildrenStopped
) {
701 return EFI_DEVICE_ERROR
;
711 IN UINTN MicroSeconds
717 Use the EFI boot services to produce a pause. This is also the routine which
718 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can
723 UnqId - Runtime O/S routine might use this, this temp routine does not use it
725 MicroSeconds - Determines the length of pause.
733 gBS
->Stall ((UINT32
) MicroSeconds
);
748 Use the PCI IO abstraction to issue memory or I/O reads and writes. This is also the routine which
749 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.
753 UnqId - Runtime O/S routine may use this field, this temp routine does not.
755 ReadWrite - Determine if it is an I/O or Memory Read/Write Operation.
757 Len - Determines the width of the data operation.
759 Port - What port to Read/Write from.
761 BuffAddr - Address to read to or write from.
769 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
770 NIC_DATA_INSTANCE
*AdapterInfo
;
772 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 0;
773 AdapterInfo
= (NIC_DATA_INSTANCE
*) (UINTN
) UnqId
;
776 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 1;
780 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 2;
784 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 3;
790 AdapterInfo
->Io_Function
->Io
.Read (
791 AdapterInfo
->Io_Function
,
796 (VOID
*) (UINTN
) (BuffAddr
)
801 AdapterInfo
->Io_Function
->Io
.Write (
802 AdapterInfo
->Io_Function
,
807 (VOID
*) (UINTN
) (BuffAddr
)
812 AdapterInfo
->Io_Function
->Mem
.Read (
813 AdapterInfo
->Io_Function
,
818 (VOID
*) (UINTN
) (BuffAddr
)
823 AdapterInfo
->Io_Function
->Mem
.Write (
824 AdapterInfo
->Io_Function
,
829 (VOID
*) (UINTN
) (BuffAddr
)
839 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevPtr
,
840 IN EFI_DEVICE_PATH_PROTOCOL
*BaseDevPtr
,
841 IN NIC_DATA_INSTANCE
*AdapterInfo
847 Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space
848 for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)
849 and an added MAC node.
853 DevPtr - Pointer which will point to the newly created device path with the MAC node attached.
855 BaseDevPtr - Pointer to the device path which the UNDI device driver is latching on to.
857 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
861 EFI_SUCCESS - A MAC address was successfully appended to the Base Device Path.
863 other - Not enough resources available to create new Device Path node.
867 EFI_MAC_ADDRESS MACAddress
;
868 PCI_CONFIG_HEADER
*CfgHdr
;
873 MAC_ADDR_DEVICE_PATH MacAddrNode
;
874 EFI_DEVICE_PATH_PROTOCOL
*EndNode
;
881 // set the environment ready (similar to UNDI_Start call) so that we can
882 // execute the other UNDI_ calls to get the mac address
883 // we are using undi 3.1 style
885 AdapterInfo
->Delay
= TmpDelay
;
886 AdapterInfo
->Virt2Phys
= (VOID
*) 0;
887 AdapterInfo
->Block
= (VOID
*) 0;
888 AdapterInfo
->Map_Mem
= (VOID
*) 0;
889 AdapterInfo
->UnMap_Mem
= (VOID
*) 0;
890 AdapterInfo
->Sync_Mem
= (VOID
*) 0;
891 AdapterInfo
->Mem_Io
= TmpMemIo
;
893 // these tmp call-backs follow 3.1 undi style
894 // i.e. they have the unique_id parameter.
896 AdapterInfo
->VersionFlag
= 0x31;
897 AdapterInfo
->Unique_ID
= (UINT64
) (UINTN
) AdapterInfo
;
902 CfgHdr
= (PCI_CONFIG_HEADER
*) &(AdapterInfo
->Config
[0]);
903 AdapterInfo
->ioaddr
= 0;
904 AdapterInfo
->RevID
= CfgHdr
->RevID
;
906 AddrLen
= E100bGetEepromAddrLen (AdapterInfo
);
908 for (Index
= 0, Index2
= 0; Index
< 3; Index
++) {
909 Val
= E100bReadEeprom (AdapterInfo
, Index
, AddrLen
);
910 MACAddress
.Addr
[Index2
++] = (UINT8
) Val
;
911 MACAddress
.Addr
[Index2
++] = (UINT8
) (Val
>> 8);
914 SetMem (MACAddress
.Addr
+ Index2
, sizeof (EFI_MAC_ADDRESS
) - Index2
, 0);
915 //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
916 // MACAddress.Addr[Index2] = 0;
921 AdapterInfo
->Delay
= (VOID
*) 0;
922 AdapterInfo
->Mem_Io
= (VOID
*) 0;
925 // fill the mac address node first
927 ZeroMem ((CHAR8
*) &MacAddrNode
, sizeof MacAddrNode
);
929 (CHAR8
*) &MacAddrNode
.MacAddress
,
930 (CHAR8
*) &MACAddress
,
931 sizeof (EFI_MAC_ADDRESS
)
934 MacAddrNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
935 MacAddrNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
936 MacAddrNode
.Header
.Length
[0] = sizeof (MacAddrNode
);
937 MacAddrNode
.Header
.Length
[1] = 0;
940 // find the size of the base dev path.
942 EndNode
= BaseDevPtr
;
944 while (!IsDevicePathEnd (EndNode
)) {
945 EndNode
= NextDevicePathNode (EndNode
);
948 BasePathLen
= (UINT16
) ((UINTN
) (EndNode
) - (UINTN
) (BaseDevPtr
));
951 // create space for full dev path
953 TotalPathLen
= (UINT16
) (BasePathLen
+ sizeof (MacAddrNode
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
955 Status
= gBS
->AllocatePool (
956 EfiRuntimeServicesData
,
961 if (Status
!= EFI_SUCCESS
) {
965 // copy the base path, mac addr and end_dev_path nodes
967 *DevPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) DevicePtr
;
968 CopyMem (DevicePtr
, (CHAR8
*) BaseDevPtr
, BasePathLen
);
969 DevicePtr
+= BasePathLen
;
970 CopyMem (DevicePtr
, (CHAR8
*) &MacAddrNode
, sizeof (MacAddrNode
));
971 DevicePtr
+= sizeof (MacAddrNode
);
972 CopyMem (DevicePtr
, (CHAR8
*) EndNode
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
985 Install a GUID/Pointer pair into the system's configuration table.
993 EFI_SUCCESS - Install a GUID/Pointer pair into the system's configuration table.
995 other - Did not successfully install the GUID/Pointer pair into the configuration table.
998 // TODO: VOID - add argument and description to function comment
1001 EFI_CONFIGURATION_TABLE
*CfgPtr
;
1004 NII_TABLE
*UndiData
;
1006 if (pxe_31
== NULL
) {
1010 if(UnidiDataPointer
== NULL
) {
1014 UndiData
= (NII_TABLE
*)UnidiDataPointer
;
1016 UndiData
->NumEntries
= pxe_31
->IFcnt
;
1017 UndiData
->NextLink
= NULL
;
1019 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
1020 UndiData
->NiiEntry
[Index
].InterfacePointer
= &UNDI32DeviceList
[Index
]->NIIProtocol_31
;
1021 UndiData
->NiiEntry
[Index
].DevicePathPointer
= UNDI32DeviceList
[Index
]->Undi32DevPath
;
1025 // see if there is an entry in the config table already
1027 CfgPtr
= gST
->ConfigurationTable
;
1029 for (Index
= 0; Index
< gST
->NumberOfTableEntries
; Index
++) {
1030 Status
= CompareGuid (
1031 &CfgPtr
->VendorGuid
,
1032 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
1034 if (Status
!= EFI_SUCCESS
) {
1041 if (Index
< gST
->NumberOfTableEntries
) {
1042 TmpData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
1045 // go to the last link
1047 while (TmpData
->NextLink
!= NULL
) {
1048 TmpData
= TmpData
->NextLink
;
1051 TmpData
->NextLink
= UndiData
;
1056 UndiData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
1060 // create an entry in the configuration table for our GUID
1062 Status
= gBS
->InstallConfigurationTable (
1063 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1071 Install driver binding protocol of UNDI.
1073 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1074 @param[in] SystemTable A pointer to the EFI System Table.
1076 @retval EFI_SUCCESS The entry point is executed successfully.
1077 @retval other Some error occurs when executing this entry point.
1083 IN EFI_HANDLE ImageHandle
,
1084 IN EFI_SYSTEM_TABLE
*SystemTable
1090 Status
= EfiLibInstallDriverBinding (
1093 &gUndiDriverBinding
,
1096 ASSERT_EFI_ERROR (Status
);
1098 Status
= gBS
->CreateEvent (
1099 EVT_SIGNAL_EXIT_BOOT_SERVICES
,
1105 ASSERT_EFI_ERROR (Status
);
1107 Status
= gBS
->CreateEvent (
1108 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
1114 ASSERT_EFI_ERROR (Status
);