diff options
author | sfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-08-24 08:25:42 +0000 |
---|---|---|
committer | sfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-08-24 08:25:42 +0000 |
commit | 9063c328dff827ef9deb1ce0dde75112c496e072 (patch) | |
tree | 7d85ebcbfb48d005ea03a252d351fc662888249d | |
parent | db999bd39b90f3515ac66c33534bd6ac95113e4d (diff) | |
download | edk2-platforms-9063c328dff827ef9deb1ce0dde75112c496e072.tar.xz |
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
-rw-r--r-- | NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c | 75 | ||||
-rw-r--r-- | NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h | 6 | ||||
-rw-r--r-- | NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c | 5 | ||||
-rw-r--r-- | NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h | 8 | ||||
-rw-r--r-- | NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c | 73 |
5 files changed, 111 insertions, 56 deletions
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c index e26b412781..e814d5a84c 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c @@ -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;
+ }
}
//
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h index ef18907aa6..d998200ce0 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h @@ -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
);
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c index 60942fb908..ecafc86a03 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c @@ -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)) {
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h index bc21b212a2..37747ac74f 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h @@ -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];
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c index ba7f948594..5f693729d6 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c @@ -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,30 +636,7 @@ EfiPxeBcDiscover ( Private->IsDoDiscover = TRUE;
- if (Info->UseUCast) {
- //
- // Do discover by unicast.
- //
- for (Index = 0; Index < Info->IpCnt; Index++) {
- if (BootSvrEntry == NULL) {
- CopyMem (&Private->ServerIp, &SrvList[Index].IpAddr, sizeof (EFI_IP_ADDRESS));
- } else {
- ASSERT (!Mode->UsingIpv6);
- ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS));
- CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS));
- }
-
- Status = PxeBcDiscoverBootServer (
- Private,
- Type,
- Layer,
- UseBis,
- &SrvList[Index].IpAddr,
- 0,
- NULL
- );
- }
- } else if (Info->UseMCast) {
+ if (Info->UseMCast) {
//
// Do discover by multicast.
//
@@ -667,8 +646,8 @@ EfiPxeBcDiscover ( Layer,
UseBis,
&Info->ServerMCastIp,
- 0,
- NULL
+ Info->IpCnt,
+ SrvList
);
} else if (Info->UseBCast) {
@@ -685,6 +664,30 @@ EfiPxeBcDiscover ( Info->IpCnt,
SrvList
);
+
+ } else if (Info->UseUCast) {
+ //
+ // Do discover by unicast.
+ //
+ for (Index = 0; Index < Info->IpCnt; Index++) {
+ if (BootSvrEntry == NULL) {
+ CopyMem (&Private->ServerIp, &SrvList[Index].IpAddr, sizeof (EFI_IP_ADDRESS));
+ } else {
+ ASSERT (!Mode->UsingIpv6);
+ ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS));
+ CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS));
+ }
+
+ Status = PxeBcDiscoverBootServer (
+ Private,
+ Type,
+ Layer,
+ UseBis,
+ &Private->ServerIp,
+ 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 {
|