mirror of https://github.com/acidanthera/audk.git
Fix bugs in PXE driver when using option 43 for boot server list and boot menu prompt.
Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Ouyang Qian <qian.ouyang@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13676 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
db999bd39b
commit
9063c328df
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Boot functions implementation for UefiPxeBc Driver.
|
||||
|
||||
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -86,9 +86,9 @@ PxeBcSelectBootPrompt (
|
|||
OfferType = Mode->UsingIpv6 ? Cache->Dhcp6.OfferType : Cache->Dhcp4.OfferType;
|
||||
|
||||
//
|
||||
// Only ProxyPxe10 offer needs boot prompt.
|
||||
// Only DhcpPxe10 and ProxyPxe10 offer needs boot prompt.
|
||||
//
|
||||
if (OfferType != PxeOfferTypeProxyPxe10) {
|
||||
if (OfferType != PxeOfferTypeProxyPxe10 && OfferType != PxeOfferTypeDhcpPxe10) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ PxeBcSelectBootPrompt (
|
|||
|
||||
VendorOpt = &Cache->Dhcp4.VendorOpt;
|
||||
if (!IS_VALID_BOOT_PROMPT (VendorOpt->BitMap)) {
|
||||
return EFI_SUCCESS;
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
Timeout = VendorOpt->MenuPrompt->Timeout;
|
||||
|
@ -110,10 +110,10 @@ PxeBcSelectBootPrompt (
|
|||
// The valid scope of Timeout refers to PXE2.1 spec.
|
||||
//
|
||||
if (Timeout == 0) {
|
||||
return EFI_SUCCESS;
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
if (Timeout == 255) {
|
||||
return EFI_TIMEOUT;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -173,6 +173,7 @@ PxeBcSelectBootPrompt (
|
|||
gST->ConOut->SetCursorPosition (gST->ConOut, SecCol + PromptLen, SecRow);
|
||||
AsciiPrint ("(%d) ", Timeout--);
|
||||
|
||||
Status = EFI_TIMEOUT;
|
||||
while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
|
||||
if (!EFI_ERROR (gBS->CheckEvent (DescendEvent))) {
|
||||
gST->ConOut->SetCursorPosition (gST->ConOut, SecCol + PromptLen, SecRow);
|
||||
|
@ -184,6 +185,7 @@ PxeBcSelectBootPrompt (
|
|||
}
|
||||
//
|
||||
// Parse the input key by user.
|
||||
// If <F8> or <Ctrl> + <M> is pressed, return success to display the boot menu.
|
||||
//
|
||||
if (InputKey.ScanCode == 0) {
|
||||
|
||||
|
@ -196,7 +198,7 @@ PxeBcSelectBootPrompt (
|
|||
case CTRL ('m'):
|
||||
case 'm':
|
||||
case 'M':
|
||||
Status = EFI_TIMEOUT;
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -208,7 +210,7 @@ PxeBcSelectBootPrompt (
|
|||
switch (InputKey.ScanCode) {
|
||||
|
||||
case SCAN_F8:
|
||||
Status = EFI_TIMEOUT;
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
|
||||
case SCAN_ESC:
|
||||
|
@ -284,10 +286,10 @@ PxeBcSelectBootMenu (
|
|||
OfferType = Mode->UsingIpv6 ? Cache->Dhcp6.OfferType : Cache->Dhcp4.OfferType;
|
||||
|
||||
//
|
||||
// There is no specified ProxyPxe10 for IPv6 in PXE and UEFI spec.
|
||||
// There is no specified DhcpPxe10/ProxyPxe10 for IPv6 in PXE and UEFI spec.
|
||||
//
|
||||
ASSERT (!Mode->UsingIpv6);
|
||||
ASSERT (OfferType == PxeOfferTypeProxyPxe10);
|
||||
ASSERT (OfferType == PxeOfferTypeProxyPxe10 || OfferType == PxeOfferTypeDhcpPxe10);
|
||||
|
||||
VendorOpt = &Cache->Dhcp4.VendorOpt;
|
||||
if (!IS_VALID_BOOT_MENU (VendorOpt->BitMap)) {
|
||||
|
@ -351,7 +353,7 @@ PxeBcSelectBootMenu (
|
|||
gBS->Stall (10 * TICKS_PER_MS);
|
||||
}
|
||||
|
||||
if (InputKey.ScanCode != 0) {
|
||||
if (InputKey.ScanCode == 0) {
|
||||
switch (InputKey.UnicodeChar) {
|
||||
case CTRL ('c'):
|
||||
InputKey.ScanCode = SCAN_ESC;
|
||||
|
@ -651,7 +653,7 @@ PxeBcDhcp6BootInfo (
|
|||
|
||||
@param[in] Private Pointer to PxeBc private data.
|
||||
@param[in] Type The type of bootstrap to perform.
|
||||
@param[in, out] Info Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO.
|
||||
@param[in, out] DiscoverInfo Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO.
|
||||
@param[out] BootEntry Pointer to PXEBC_BOOT_SVR_ENTRY.
|
||||
@param[out] SrvList Pointer to EFI_PXE_BASE_CODE_SRVLIST.
|
||||
|
||||
|
@ -663,7 +665,7 @@ EFI_STATUS
|
|||
PxeBcExtractDiscoverInfo (
|
||||
IN PXEBC_PRIVATE_DATA *Private,
|
||||
IN UINT16 Type,
|
||||
IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info,
|
||||
IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO **DiscoverInfo,
|
||||
OUT PXEBC_BOOT_SVR_ENTRY **BootEntry,
|
||||
OUT EFI_PXE_BASE_CODE_SRVLIST **SrvList
|
||||
)
|
||||
|
@ -673,8 +675,11 @@ PxeBcExtractDiscoverInfo (
|
|||
PXEBC_VENDOR_OPTION *VendorOpt;
|
||||
PXEBC_BOOT_SVR_ENTRY *Entry;
|
||||
BOOLEAN IsFound;
|
||||
EFI_PXE_BASE_CODE_DISCOVER_INFO *Info;
|
||||
UINT16 Index;
|
||||
|
||||
Mode = Private->PxeBc.Mode;
|
||||
Info = *DiscoverInfo;
|
||||
|
||||
if (Mode->UsingIpv6) {
|
||||
Info->IpCnt = 1;
|
||||
|
@ -708,7 +713,7 @@ PxeBcExtractDiscoverInfo (
|
|||
Info->UseMCast = (BOOLEAN) !IS_DISABLE_MCAST_DISCOVER (VendorOpt->DiscoverCtrl);
|
||||
Info->UseBCast = (BOOLEAN) !IS_DISABLE_BCAST_DISCOVER (VendorOpt->DiscoverCtrl);
|
||||
Info->MustUseList = (BOOLEAN) IS_ENABLE_USE_SERVER_LIST (VendorOpt->DiscoverCtrl);
|
||||
Info->UseUCast = Info->MustUseList;
|
||||
Info->UseUCast = (BOOLEAN) IS_VALID_BOOT_SERVERS (VendorOpt->BitMap);
|
||||
|
||||
if (Info->UseMCast) {
|
||||
//
|
||||
|
@ -719,7 +724,7 @@ PxeBcExtractDiscoverInfo (
|
|||
|
||||
Info->IpCnt = 0;
|
||||
|
||||
if (Info->MustUseList) {
|
||||
if (Info->UseUCast) {
|
||||
Entry = VendorOpt->BootSvr;
|
||||
|
||||
while (((UINT8) (Entry - VendorOpt->BootSvr)) < VendorOpt->BootSvrLen) {
|
||||
|
@ -735,9 +740,24 @@ PxeBcExtractDiscoverInfo (
|
|||
}
|
||||
|
||||
Info->IpCnt = Entry->IpCnt;
|
||||
if (Info->IpCnt >= 1) {
|
||||
*DiscoverInfo = AllocatePool (sizeof (*Info) + (Info->IpCnt - 1) * sizeof (**SrvList));
|
||||
if (*DiscoverInfo == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (*DiscoverInfo, Info, sizeof (*Info));
|
||||
Info = *DiscoverInfo;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Info->IpCnt; Index++) {
|
||||
CopyMem (&Info->SrvList[Index].IpAddr, &Entry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS));
|
||||
Info->SrvList[Index].AcceptAnyResponse = !Info->MustUseList;
|
||||
Info->SrvList[Index].Type = NTOHS (Entry->Type);
|
||||
}
|
||||
}
|
||||
|
||||
*BootEntry = Entry;
|
||||
*SrvList = Info->SrvList;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
@ -842,12 +862,12 @@ PxeBcDiscoverBootFile (
|
|||
//
|
||||
// Choose by user's input.
|
||||
//
|
||||
Status = PxeBcSelectBootMenu (Private, &Type, TRUE);
|
||||
Status = PxeBcSelectBootMenu (Private, &Type, FALSE);
|
||||
} else if (Status == EFI_TIMEOUT) {
|
||||
//
|
||||
// Choose by default item.
|
||||
//
|
||||
Status = PxeBcSelectBootMenu (Private, &Type, FALSE);
|
||||
Status = PxeBcSelectBootMenu (Private, &Type, TRUE);
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
@ -868,6 +888,27 @@ PxeBcDiscoverBootFile (
|
|||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Mode->PxeReplyReceived && !Mode->ProxyOfferReceived) {
|
||||
//
|
||||
// Some network boot loader only search the packet in Mode.ProxyOffer to get its server
|
||||
// IP address, so we need to store a copy of Mode.PxeReply packet into Mode.ProxyOffer.
|
||||
//
|
||||
if (Mode->UsingIpv6) {
|
||||
CopyMem (
|
||||
&Mode->ProxyOffer.Dhcpv6,
|
||||
&Mode->PxeReply.Dhcpv6,
|
||||
Private->PxeReply.Dhcp6.Packet.Ack.Length
|
||||
);
|
||||
} else {
|
||||
CopyMem (
|
||||
&Mode->ProxyOffer.Dhcpv4,
|
||||
&Mode->PxeReply.Dhcpv4,
|
||||
Private->PxeReply.Dhcp4.Packet.Ack.Length
|
||||
);
|
||||
}
|
||||
Mode->ProxyOfferReceived = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Boot functions declaration for UefiPxeBc Driver.
|
||||
|
||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -29,7 +29,7 @@
|
|||
|
||||
@param[in] Private Pointer to PxeBc private data.
|
||||
@param[in] Type The type of bootstrap to perform.
|
||||
@param[in, out] Info Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO.
|
||||
@param[in, out] DiscoverInfo Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO.
|
||||
@param[out] BootEntry Pointer to PXEBC_BOOT_SVR_ENTRY.
|
||||
@param[out] SrvList Pointer to EFI_PXE_BASE_CODE_SRVLIST.
|
||||
|
||||
|
@ -41,7 +41,7 @@ EFI_STATUS
|
|||
PxeBcExtractDiscoverInfo (
|
||||
IN PXEBC_PRIVATE_DATA *Private,
|
||||
IN UINT16 Type,
|
||||
IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info,
|
||||
IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO **DiscoverInfo,
|
||||
OUT PXEBC_BOOT_SVR_ENTRY **BootEntry,
|
||||
OUT EFI_PXE_BASE_CODE_SRVLIST **SrvList
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Functions implementation related with DHCPv4 for UefiPxeBc Driver.
|
||||
|
||||
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -1443,7 +1443,7 @@ PxeBcDhcp4Discover (
|
|||
break;
|
||||
}
|
||||
if ((SrvList[SrvIndex].Type == Type) &&
|
||||
EFI_IP4_EQUAL (&Response->Dhcp4.Header.ServerAddr, &Private->ServerIp)) {
|
||||
EFI_IP4_EQUAL (&Response->Dhcp4.Header.ServerAddr, &SrvList[SrvIndex].IpAddr)) {
|
||||
break;
|
||||
}
|
||||
SrvIndex++;
|
||||
|
@ -1587,6 +1587,7 @@ PxeBcDhcp4Dora (
|
|||
AsciiPrint ("\n Station IP address is ");
|
||||
|
||||
PxeBcShowIp4Addr (&Private->StationIp.v4);
|
||||
AsciiPrint ("\n");
|
||||
|
||||
ON_EXIT:
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Functions declaration related with DHCPv4 for UefiPxeBc Driver.
|
||||
|
||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -146,6 +146,10 @@ typedef enum {
|
|||
BIT (PXEBC_VENDOR_TAG_BOOT_MENU) | \
|
||||
BIT (PXEBC_VENDOR_TAG_MENU_PROMPT))
|
||||
|
||||
#define IS_VALID_BOOT_SERVERS(x) \
|
||||
((((x)[0]) & BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS)) \
|
||||
== BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS))
|
||||
|
||||
#define IS_VALID_BOOT_PROMPT(x) \
|
||||
((((x)[0]) & BIT (PXEBC_VENDOR_TAG_MENU_PROMPT)) \
|
||||
== BIT (PXEBC_VENDOR_TAG_MENU_PROMPT))
|
||||
|
@ -256,6 +260,7 @@ typedef union {
|
|||
PXEBC_DHCP4_OPTION_MAX_MESG_SIZE *MaxMesgSize;
|
||||
} PXEBC_DHCP4_OPTION_ENTRY;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
UINT8 IpCnt;
|
||||
|
@ -272,6 +277,7 @@ typedef struct {
|
|||
UINT8 Timeout;
|
||||
UINT8 Prompt[1];
|
||||
} PXEBC_MENU_PROMPT;
|
||||
#pragma pack()
|
||||
|
||||
typedef struct {
|
||||
UINT32 BitMap[8];
|
||||
|
|
|
@ -529,6 +529,7 @@ EfiPxeBcDiscover (
|
|||
UINT16 Index;
|
||||
EFI_STATUS Status;
|
||||
EFI_PXE_BASE_CODE_IP_FILTER IpFilter;
|
||||
EFI_PXE_BASE_CODE_DISCOVER_INFO *NewCreatedInfo;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
@ -541,6 +542,7 @@ EfiPxeBcDiscover (
|
|||
SrvList = NULL;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER;
|
||||
NewCreatedInfo = NULL;
|
||||
|
||||
if (!Mode->Started) {
|
||||
return EFI_NOT_STARTED;
|
||||
|
@ -594,12 +596,12 @@ EfiPxeBcDiscover (
|
|||
//
|
||||
// 2. Extract the discover information from the cached packets if unspecified.
|
||||
//
|
||||
Info = &DefaultInfo;
|
||||
Status = PxeBcExtractDiscoverInfo (Private, Type, Info, &BootSvrEntry, &SrvList);
|
||||
NewCreatedInfo = &DefaultInfo;
|
||||
Status = PxeBcExtractDiscoverInfo (Private, Type, &NewCreatedInfo, &BootSvrEntry, &SrvList);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Info = NewCreatedInfo;
|
||||
} else {
|
||||
//
|
||||
// 3. Take the pass-in information as the discover info, and validate the server list.
|
||||
|
@ -634,7 +636,36 @@ EfiPxeBcDiscover (
|
|||
|
||||
Private->IsDoDiscover = TRUE;
|
||||
|
||||
if (Info->UseUCast) {
|
||||
if (Info->UseMCast) {
|
||||
//
|
||||
// Do discover by multicast.
|
||||
//
|
||||
Status = PxeBcDiscoverBootServer (
|
||||
Private,
|
||||
Type,
|
||||
Layer,
|
||||
UseBis,
|
||||
&Info->ServerMCastIp,
|
||||
Info->IpCnt,
|
||||
SrvList
|
||||
);
|
||||
|
||||
} else if (Info->UseBCast) {
|
||||
//
|
||||
// Do discover by broadcast, but only valid for IPv4.
|
||||
//
|
||||
ASSERT (!Mode->UsingIpv6);
|
||||
Status = PxeBcDiscoverBootServer (
|
||||
Private,
|
||||
Type,
|
||||
Layer,
|
||||
UseBis,
|
||||
NULL,
|
||||
Info->IpCnt,
|
||||
SrvList
|
||||
);
|
||||
|
||||
} else if (Info->UseUCast) {
|
||||
//
|
||||
// Do discover by unicast.
|
||||
//
|
||||
|
@ -652,39 +683,11 @@ EfiPxeBcDiscover (
|
|||
Type,
|
||||
Layer,
|
||||
UseBis,
|
||||
&SrvList[Index].IpAddr,
|
||||
0,
|
||||
NULL
|
||||
&Private->ServerIp,
|
||||
Info->IpCnt,
|
||||
SrvList
|
||||
);
|
||||
}
|
||||
} else if (Info->UseMCast) {
|
||||
//
|
||||
// Do discover by multicast.
|
||||
//
|
||||
Status = PxeBcDiscoverBootServer (
|
||||
Private,
|
||||
Type,
|
||||
Layer,
|
||||
UseBis,
|
||||
&Info->ServerMCastIp,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
} else if (Info->UseBCast) {
|
||||
//
|
||||
// Do discover by broadcast, but only valid for IPv4.
|
||||
//
|
||||
ASSERT (!Mode->UsingIpv6);
|
||||
Status = PxeBcDiscoverBootServer (
|
||||
Private,
|
||||
Type,
|
||||
Layer,
|
||||
UseBis,
|
||||
NULL,
|
||||
Info->IpCnt,
|
||||
SrvList
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -698,8 +701,8 @@ EfiPxeBcDiscover (
|
|||
if (!EFI_ERROR (Status)) {
|
||||
CopyMem (
|
||||
&Mode->PxeReply.Dhcpv6,
|
||||
&Private->PxeReply.Dhcp6.Packet.Offer,
|
||||
Private->PxeReply.Dhcp6.Packet.Offer.Length
|
||||
&Private->PxeReply.Dhcp6.Packet.Ack.Dhcp6,
|
||||
Private->PxeReply.Dhcp6.Packet.Ack.Length
|
||||
);
|
||||
Mode->PxeReplyReceived = TRUE;
|
||||
Mode->PxeDiscoverValid = TRUE;
|
||||
|
@ -709,8 +712,8 @@ EfiPxeBcDiscover (
|
|||
if (!EFI_ERROR (Status)) {
|
||||
CopyMem (
|
||||
&Mode->PxeReply.Dhcpv4,
|
||||
&Private->PxeReply.Dhcp4.Packet.Offer,
|
||||
Private->PxeReply.Dhcp4.Packet.Offer.Length
|
||||
&Private->PxeReply.Dhcp4.Packet.Ack.Dhcp4,
|
||||
Private->PxeReply.Dhcp4.Packet.Ack.Length
|
||||
);
|
||||
Mode->PxeReplyReceived = TRUE;
|
||||
Mode->PxeDiscoverValid = TRUE;
|
||||
|
@ -720,6 +723,10 @@ EfiPxeBcDiscover (
|
|||
|
||||
ON_EXIT:
|
||||
|
||||
if (NewCreatedInfo != NULL && NewCreatedInfo != &DefaultInfo) {
|
||||
FreePool (NewCreatedInfo);
|
||||
}
|
||||
|
||||
if (Mode->UsingIpv6) {
|
||||
Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue