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
;
291 Status
= gBS
->OpenProtocol (
293 &gEfiPciIoProtocolGuid
,
294 (VOID
**) &PciIoFncs
,
295 This
->DriverBindingHandle
,
297 EFI_OPEN_PROTOCOL_BY_DRIVER
300 if (EFI_ERROR (Status
)) {
304 Status
= gBS
->OpenProtocol (
306 &gEfiDevicePathProtocolGuid
,
307 (VOID
**) &UndiDevicePath
,
308 This
->DriverBindingHandle
,
310 EFI_OPEN_PROTOCOL_BY_DRIVER
313 if (EFI_ERROR (Status
)) {
316 &gEfiPciIoProtocolGuid
,
317 This
->DriverBindingHandle
,
324 Status
= gBS
->AllocatePool (
325 EfiRuntimeServicesData
,
327 (VOID
**) &UNDI32Device
330 if (EFI_ERROR (Status
)) {
334 ZeroMem ((CHAR8
*) UNDI32Device
, sizeof (UNDI32_DEV
));
337 // allocate and initialize both (old and new) the !pxe structures here,
338 // there should only be one copy of each of these structure for any number
339 // of NICs this undi supports. Also, these structures need to be on a
340 // paragraph boundary as per the spec. so, while allocating space for these,
341 // make sure that there is space for 2 !pxe structures (old and new) and a
342 // 32 bytes padding for alignment adjustment (in case)
344 TmpPxePointer
= NULL
;
345 if (pxe_31
== NULL
) {
346 Status
= gBS
->AllocatePool (
347 EfiRuntimeServicesData
,
348 (sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32),
349 (VOID
**) &TmpPxePointer
352 if (EFI_ERROR (Status
)) {
353 goto UndiErrorDeleteDevice
;
358 sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32
361 // check for paragraph alignment here, assuming that the pointer is
362 // already 8 byte aligned.
364 if (((UINTN
) TmpPxePointer
& 0x0F) != 0) {
365 pxe_31
= (PXE_SW_UNDI
*) ((UINTN
) (TmpPxePointer
+ 8));
367 pxe_31
= (PXE_SW_UNDI
*) TmpPxePointer
;
370 // assuming that the sizeof pxe_31 is a 16 byte multiple
372 pxe
= (PXE_SW_UNDI
*) ((CHAR8
*) (pxe_31
) + sizeof (PXE_SW_UNDI
));
374 PxeStructInit (pxe
, 0x30);
375 PxeStructInit (pxe_31
, 0x31);
378 UNDI32Device
->NIIProtocol
.ID
= (UINT64
) (UINTN
) (pxe
);
379 UNDI32Device
->NIIProtocol_31
.ID
= (UINT64
) (UINTN
) (pxe_31
);
381 Status
= PciIoFncs
->Attributes (
383 EfiPciIoAttributeOperationEnable
,
384 EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_MEMORY
| EFI_PCI_IO_ATTRIBUTE_IO
| EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
,
388 // Read all the registers from device's PCI Configuration space
390 Status
= PciIoFncs
->Pci
.Read (
395 &UNDI32Device
->NicInfo
.Config
398 CfgHdr
= (PCI_CONFIG_HEADER
*) &(UNDI32Device
->NicInfo
.Config
[0]);
401 // make sure that this device is a PCI bus master
404 NewCommand
= (UINT16
) (CfgHdr
->Command
| PCI_COMMAND_MASTER
| PCI_COMMAND_IO
);
405 if (CfgHdr
->Command
!= NewCommand
) {
406 PciIoFncs
->Pci
.Write (
413 CfgHdr
->Command
= NewCommand
;
417 // make sure that the latency timer is at least 32
419 if (CfgHdr
->LatencyTimer
< 32) {
420 CfgHdr
->LatencyTimer
= 32;
421 PciIoFncs
->Pci
.Write (
426 &CfgHdr
->LatencyTimer
430 // the IfNum index for the current interface will be the total number
431 // of interfaces initialized so far
433 UNDI32Device
->NIIProtocol
.IfNum
= pxe
->IFcnt
;
434 UNDI32Device
->NIIProtocol_31
.IfNum
= pxe_31
->IFcnt
;
436 PxeUpdate (&UNDI32Device
->NicInfo
, pxe
);
437 PxeUpdate (&UNDI32Device
->NicInfo
, pxe_31
);
439 UNDI32Device
->NicInfo
.Io_Function
= PciIoFncs
;
440 UNDI32DeviceList
[UNDI32Device
->NIIProtocol
.IfNum
] = UNDI32Device
;
441 UNDI32Device
->Undi32BaseDevPath
= UndiDevicePath
;
443 Status
= AppendMac2DevPath (
444 &UNDI32Device
->Undi32DevPath
,
445 UNDI32Device
->Undi32BaseDevPath
,
446 &UNDI32Device
->NicInfo
450 goto UndiErrorDeletePxe
;
453 UNDI32Device
->Signature
= UNDI_DEV_SIGNATURE
;
455 UNDI32Device
->NIIProtocol
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION
;
456 UNDI32Device
->NIIProtocol
.Type
= EfiNetworkInterfaceUndi
;
457 UNDI32Device
->NIIProtocol
.MajorVer
= PXE_ROMID_MAJORVER
;
458 UNDI32Device
->NIIProtocol
.MinorVer
= PXE_ROMID_MINORVER
;
459 UNDI32Device
->NIIProtocol
.ImageSize
= 0;
460 UNDI32Device
->NIIProtocol
.ImageAddr
= 0;
461 UNDI32Device
->NIIProtocol
.Ipv6Supported
= FALSE
;
463 UNDI32Device
->NIIProtocol
.StringId
[0] = 'U';
464 UNDI32Device
->NIIProtocol
.StringId
[1] = 'N';
465 UNDI32Device
->NIIProtocol
.StringId
[2] = 'D';
466 UNDI32Device
->NIIProtocol
.StringId
[3] = 'I';
468 UNDI32Device
->NIIProtocol_31
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31
;
469 UNDI32Device
->NIIProtocol_31
.Type
= EfiNetworkInterfaceUndi
;
470 UNDI32Device
->NIIProtocol_31
.MajorVer
= PXE_ROMID_MAJORVER
;
471 UNDI32Device
->NIIProtocol_31
.MinorVer
= PXE_ROMID_MINORVER_31
;
472 UNDI32Device
->NIIProtocol_31
.ImageSize
= 0;
473 UNDI32Device
->NIIProtocol_31
.ImageAddr
= 0;
474 UNDI32Device
->NIIProtocol_31
.Ipv6Supported
= FALSE
;
476 UNDI32Device
->NIIProtocol_31
.StringId
[0] = 'U';
477 UNDI32Device
->NIIProtocol_31
.StringId
[1] = 'N';
478 UNDI32Device
->NIIProtocol_31
.StringId
[2] = 'D';
479 UNDI32Device
->NIIProtocol_31
.StringId
[3] = 'I';
481 UNDI32Device
->DeviceHandle
= NULL
;
484 // install both the 3.0 and 3.1 NII protocols.
486 Status
= gBS
->InstallMultipleProtocolInterfaces (
487 &UNDI32Device
->DeviceHandle
,
488 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
489 &UNDI32Device
->NIIProtocol_31
,
490 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
491 &UNDI32Device
->NIIProtocol
,
492 &gEfiDevicePathProtocolGuid
,
493 UNDI32Device
->Undi32DevPath
,
497 if (EFI_ERROR (Status
)) {
498 goto UndiErrorDeleteDevicePath
;
502 // if the table exists, free it and alloc again, or alloc it directly
504 if (UnidiDataPointer
!= NULL
) {
505 Status
= gBS
->FreePool(UnidiDataPointer
);
507 if (EFI_ERROR (Status
)) {
508 goto UndiErrorDeleteDevicePath
;
511 Len
= (pxe_31
->IFcnt
* sizeof (NII_ENTRY
)) + sizeof (UnidiDataPointer
);
512 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, Len
, (VOID
**) &UnidiDataPointer
);
514 if (EFI_ERROR (Status
)) {
515 goto UndiErrorAllocDataPointer
;
519 // Open For Child Device
521 Status
= gBS
->OpenProtocol (
523 &gEfiPciIoProtocolGuid
,
524 (VOID
**) &PciIoFncs
,
525 This
->DriverBindingHandle
,
526 UNDI32Device
->DeviceHandle
,
527 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
531 UndiErrorAllocDataPointer
:
532 gBS
->UninstallMultipleProtocolInterfaces (
533 &UNDI32Device
->DeviceHandle
,
534 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
535 &UNDI32Device
->NIIProtocol_31
,
536 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
537 &UNDI32Device
->NIIProtocol
,
538 &gEfiDevicePathProtocolGuid
,
539 UNDI32Device
->Undi32DevPath
,
543 UndiErrorDeleteDevicePath
:
544 UNDI32DeviceList
[UNDI32Device
->NIIProtocol
.IfNum
] = NULL
;
545 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
548 PxeUpdate (NULL
, pxe
);
549 PxeUpdate (NULL
, pxe_31
);
550 if (TmpPxePointer
!= NULL
) {
551 gBS
->FreePool (TmpPxePointer
);
555 UndiErrorDeleteDevice
:
556 gBS
->FreePool (UNDI32Device
);
561 &gEfiDevicePathProtocolGuid
,
562 This
->DriverBindingHandle
,
568 &gEfiPciIoProtocolGuid
,
569 This
->DriverBindingHandle
,
579 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
580 IN EFI_HANDLE Controller
,
581 IN UINTN NumberOfChildren
,
582 IN EFI_HANDLE
*ChildHandleBuffer
587 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
588 closing the DevicePath and PciIo protocols on Controller.
591 This - Protocol instance pointer.
592 Controller - Handle of device to stop driver on.
593 NumberOfChildren - How many children need to be stopped.
594 ChildHandleBuffer - Not used.
597 EFI_SUCCESS - This driver is removed Controller.
598 other - This driver was not removed from this device.
601 // TODO: EFI_DEVICE_ERROR - add return value to function comment
604 BOOLEAN AllChildrenStopped
;
606 UNDI32_DEV
*UNDI32Device
;
607 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NIIProtocol
;
608 EFI_PCI_IO_PROTOCOL
*PciIo
;
611 // Complete all outstanding transactions to Controller.
612 // Don't allow any new transaction to Controller to be started.
614 if (NumberOfChildren
== 0) {
617 // Close the bus driver
619 Status
= gBS
->CloseProtocol (
621 &gEfiDevicePathProtocolGuid
,
622 This
->DriverBindingHandle
,
626 Status
= gBS
->CloseProtocol (
628 &gEfiPciIoProtocolGuid
,
629 This
->DriverBindingHandle
,
636 AllChildrenStopped
= TRUE
;
638 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
640 Status
= gBS
->OpenProtocol (
641 ChildHandleBuffer
[Index
],
642 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
643 (VOID
**) &NIIProtocol
,
644 This
->DriverBindingHandle
,
646 EFI_OPEN_PROTOCOL_GET_PROTOCOL
648 if (!EFI_ERROR (Status
)) {
650 UNDI32Device
= UNDI_DEV_FROM_THIS (NIIProtocol
);
652 Status
= gBS
->CloseProtocol (
654 &gEfiPciIoProtocolGuid
,
655 This
->DriverBindingHandle
,
656 ChildHandleBuffer
[Index
]
659 Status
= gBS
->UninstallMultipleProtocolInterfaces (
660 ChildHandleBuffer
[Index
],
661 &gEfiDevicePathProtocolGuid
,
662 UNDI32Device
->Undi32DevPath
,
663 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
664 &UNDI32Device
->NIIProtocol_31
,
665 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
666 &UNDI32Device
->NIIProtocol
,
670 if (EFI_ERROR (Status
)) {
673 &gEfiPciIoProtocolGuid
,
675 This
->DriverBindingHandle
,
676 ChildHandleBuffer
[Index
],
677 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
680 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
681 gBS
->FreePool (UNDI32Device
);
685 if (EFI_ERROR (Status
)) {
686 AllChildrenStopped
= FALSE
;
690 if (!AllChildrenStopped
) {
691 return EFI_DEVICE_ERROR
;
701 IN UINTN MicroSeconds
707 Use the EFI boot services to produce a pause. This is also the routine which
708 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can
713 UnqId - Runtime O/S routine might use this, this temp routine does not use it
715 MicroSeconds - Determines the length of pause.
723 gBS
->Stall ((UINT32
) MicroSeconds
);
738 Use the PCI IO abstraction to issue memory or I/O reads and writes. This is also the routine which
739 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.
743 UnqId - Runtime O/S routine may use this field, this temp routine does not.
745 ReadWrite - Determine if it is an I/O or Memory Read/Write Operation.
747 Len - Determines the width of the data operation.
749 Port - What port to Read/Write from.
751 BuffAddr - Address to read to or write from.
759 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
760 NIC_DATA_INSTANCE
*AdapterInfo
;
762 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 0;
763 AdapterInfo
= (NIC_DATA_INSTANCE
*) (UINTN
) UnqId
;
766 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 1;
770 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 2;
774 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 3;
780 AdapterInfo
->Io_Function
->Io
.Read (
781 AdapterInfo
->Io_Function
,
786 (VOID
*) (UINTN
) (BuffAddr
)
791 AdapterInfo
->Io_Function
->Io
.Write (
792 AdapterInfo
->Io_Function
,
797 (VOID
*) (UINTN
) (BuffAddr
)
802 AdapterInfo
->Io_Function
->Mem
.Read (
803 AdapterInfo
->Io_Function
,
808 (VOID
*) (UINTN
) (BuffAddr
)
813 AdapterInfo
->Io_Function
->Mem
.Write (
814 AdapterInfo
->Io_Function
,
819 (VOID
*) (UINTN
) (BuffAddr
)
829 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevPtr
,
830 IN EFI_DEVICE_PATH_PROTOCOL
*BaseDevPtr
,
831 IN NIC_DATA_INSTANCE
*AdapterInfo
837 Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space
838 for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)
839 and an added MAC node.
843 DevPtr - Pointer which will point to the newly created device path with the MAC node attached.
845 BaseDevPtr - Pointer to the device path which the UNDI device driver is latching on to.
847 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
851 EFI_SUCCESS - A MAC address was successfully appended to the Base Device Path.
853 other - Not enough resources available to create new Device Path node.
857 EFI_MAC_ADDRESS MACAddress
;
858 PCI_CONFIG_HEADER
*CfgHdr
;
863 MAC_ADDR_DEVICE_PATH MacAddrNode
;
864 EFI_DEVICE_PATH_PROTOCOL
*EndNode
;
871 // set the environment ready (similar to UNDI_Start call) so that we can
872 // execute the other UNDI_ calls to get the mac address
873 // we are using undi 3.1 style
875 AdapterInfo
->Delay
= TmpDelay
;
876 AdapterInfo
->Virt2Phys
= (VOID
*) 0;
877 AdapterInfo
->Block
= (VOID
*) 0;
878 AdapterInfo
->Map_Mem
= (VOID
*) 0;
879 AdapterInfo
->UnMap_Mem
= (VOID
*) 0;
880 AdapterInfo
->Sync_Mem
= (VOID
*) 0;
881 AdapterInfo
->Mem_Io
= TmpMemIo
;
883 // these tmp call-backs follow 3.1 undi style
884 // i.e. they have the unique_id parameter.
886 AdapterInfo
->VersionFlag
= 0x31;
887 AdapterInfo
->Unique_ID
= (UINT64
) (UINTN
) AdapterInfo
;
892 CfgHdr
= (PCI_CONFIG_HEADER
*) &(AdapterInfo
->Config
[0]);
893 AdapterInfo
->ioaddr
= 0;
894 AdapterInfo
->RevID
= CfgHdr
->RevID
;
896 AddrLen
= E100bGetEepromAddrLen (AdapterInfo
);
898 for (Index
= 0, Index2
= 0; Index
< 3; Index
++) {
899 Val
= E100bReadEeprom (AdapterInfo
, Index
, AddrLen
);
900 MACAddress
.Addr
[Index2
++] = (UINT8
) Val
;
901 MACAddress
.Addr
[Index2
++] = (UINT8
) (Val
>> 8);
904 SetMem (MACAddress
.Addr
+ Index2
, sizeof (EFI_MAC_ADDRESS
) - Index2
, 0);
905 //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
906 // MACAddress.Addr[Index2] = 0;
911 AdapterInfo
->Delay
= (VOID
*) 0;
912 AdapterInfo
->Mem_Io
= (VOID
*) 0;
915 // fill the mac address node first
917 ZeroMem ((CHAR8
*) &MacAddrNode
, sizeof MacAddrNode
);
919 (CHAR8
*) &MacAddrNode
.MacAddress
,
920 (CHAR8
*) &MACAddress
,
921 sizeof (EFI_MAC_ADDRESS
)
924 MacAddrNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
925 MacAddrNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
926 MacAddrNode
.Header
.Length
[0] = sizeof (MacAddrNode
);
927 MacAddrNode
.Header
.Length
[1] = 0;
930 // find the size of the base dev path.
932 EndNode
= BaseDevPtr
;
934 while (!IsDevicePathEnd (EndNode
)) {
935 EndNode
= NextDevicePathNode (EndNode
);
938 BasePathLen
= (UINT16
) ((UINTN
) (EndNode
) - (UINTN
) (BaseDevPtr
));
941 // create space for full dev path
943 TotalPathLen
= (UINT16
) (BasePathLen
+ sizeof (MacAddrNode
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
945 Status
= gBS
->AllocatePool (
946 EfiRuntimeServicesData
,
951 if (Status
!= EFI_SUCCESS
) {
955 // copy the base path, mac addr and end_dev_path nodes
957 *DevPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) DevicePtr
;
958 CopyMem (DevicePtr
, (CHAR8
*) BaseDevPtr
, BasePathLen
);
959 DevicePtr
+= BasePathLen
;
960 CopyMem (DevicePtr
, (CHAR8
*) &MacAddrNode
, sizeof (MacAddrNode
));
961 DevicePtr
+= sizeof (MacAddrNode
);
962 CopyMem (DevicePtr
, (CHAR8
*) EndNode
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
975 Install a GUID/Pointer pair into the system's configuration table.
983 EFI_SUCCESS - Install a GUID/Pointer pair into the system's configuration table.
985 other - Did not successfully install the GUID/Pointer pair into the configuration table.
988 // TODO: VOID - add argument and description to function comment
991 EFI_CONFIGURATION_TABLE
*CfgPtr
;
996 if (pxe_31
== NULL
) {
1000 if(UnidiDataPointer
== NULL
) {
1004 UndiData
= (NII_TABLE
*)UnidiDataPointer
;
1006 UndiData
->NumEntries
= pxe_31
->IFcnt
;
1007 UndiData
->NextLink
= NULL
;
1009 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
1010 UndiData
->NiiEntry
[Index
].InterfacePointer
= &UNDI32DeviceList
[Index
]->NIIProtocol_31
;
1011 UndiData
->NiiEntry
[Index
].DevicePathPointer
= UNDI32DeviceList
[Index
]->Undi32DevPath
;
1015 // see if there is an entry in the config table already
1017 CfgPtr
= gST
->ConfigurationTable
;
1019 for (Index
= 0; Index
< gST
->NumberOfTableEntries
; Index
++) {
1020 Status
= CompareGuid (
1021 &CfgPtr
->VendorGuid
,
1022 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
1024 if (Status
!= EFI_SUCCESS
) {
1031 if (Index
< gST
->NumberOfTableEntries
) {
1032 TmpData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
1035 // go to the last link
1037 while (TmpData
->NextLink
!= NULL
) {
1038 TmpData
= TmpData
->NextLink
;
1041 TmpData
->NextLink
= UndiData
;
1046 UndiData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
1050 // create an entry in the configuration table for our GUID
1052 Status
= gBS
->InstallConfigurationTable (
1053 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1061 Install driver binding protocol of UNDI.
1063 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1064 @param[in] SystemTable A pointer to the EFI System Table.
1066 @retval EFI_SUCCESS The entry point is executed successfully.
1067 @retval other Some error occurs when executing this entry point.
1073 IN EFI_HANDLE ImageHandle
,
1074 IN EFI_SYSTEM_TABLE
*SystemTable
1080 Status
= EfiLibInstallDriverBinding (
1083 &gUndiDriverBinding
,
1086 ASSERT_EFI_ERROR (Status
);
1088 Status
= gBS
->CreateEvent (
1089 EVT_SIGNAL_EXIT_BOOT_SERVICES
,
1095 ASSERT_EFI_ERROR (Status
);
1097 Status
= gBS
->CreateEvent (
1098 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
1104 ASSERT_EFI_ERROR (Status
);