bc.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,547 行 · 第 1/5 页
C
2,547 行
break;
}
//
// Packet was received. Make received callback then return.
//
if (CallbackPtr != NULL) {
StatCode = CallbackPtr (
Private->CallbackProtocolPtr,
Function,
TRUE,
(UINT32) *BufferSizePtr,
(EFI_PXE_BASE_CODE_PACKET *) Private->ReceiveBufferPtr
);
if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
StatCode = EFI_ABORTED;
} else {
StatCode = EFI_SUCCESS;
}
}
break;
}
#else
//
// Poll for received packet.
//
*BufferSizePtr = BUFFER_ALLOCATE_SIZE;
StatCode = SnpPtr->Receive (
SnpPtr,
HeaderSizePtr,
BufferSizePtr,
Private->ReceiveBufferPtr,
0,
0,
ProtocolPtr
);
if (!EFI_ERROR (StatCode)) {
//
// Packet was received. Make received callback then return.
//
if (CallbackPtr != NULL) {
StatCode = CallbackPtr (
Private->CallbackProtocolPtr,
Function,
TRUE,
(UINT32) *BufferSizePtr,
(EFI_PXE_BASE_CODE_PACKET *) Private->ReceiveBufferPtr
);
if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
StatCode = EFI_ABORTED;
} else {
StatCode = EFI_SUCCESS;
}
}
break;
}
if (StatCode != EFI_NOT_READY) {
break;
}
#endif
//
// Check for callback event.
//
if (!EFI_ERROR (gBS->CheckEvent (CallbackEvent))) {
//
// Make periodic callback if callback pointer is initialized.
//
if (CallbackPtr != NULL) {
StatCode = CallbackPtr (
Private->CallbackProtocolPtr,
Function,
FALSE,
0,
NULL
);
//
// Abort if directed to by callback routine.
//
if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
StatCode = EFI_ABORTED;
break;
}
}
}
//
// Check for timeout event.
//
if (TimeoutEvent == 0) {
StatCode = EFI_TIMEOUT;
break;
}
if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
StatCode = EFI_TIMEOUT;
break;
}
//
// Check IGMP timer events.
//
IgmpCheckTimers (Private);
}
gBS->CloseEvent (CallbackEvent);
return StatCode;
}
EFI_STATUS
SendPacket (
PXE_BASECODE_DEVICE *Private,
VOID *HeaderPtr,
VOID *PacketPtr,
INTN PacketLen,
VOID *HardwareAddr,
UINT16 MediaProtocol,
IN EFI_PXE_BASE_CODE_FUNCTION Function
)
/*++
Routine Description:
Routine which does an SNP->Transmit of a buffer
Arguments:
Private - Pointer to Pxe BaseCode Protocol
HeaderPtr - Pointer to the buffer
PacketPtr - Pointer to the packet to send
PacketLen - The length of the entire packet to send
HardwareAddr - Pointer to the MAC address of the destination
MediaProtocol - What type of frame to create (RFC 1700) - IE. Ethernet
Function - What PXE function to callback
Returns:
0 - Something was sent
!0 - An error was encountered during sending of a packet
--*/
{
EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;
EFI_SIMPLE_NETWORK_MODE *SnpModePtr;
EFI_PXE_CALLBACK CallbackPtr;
EFI_STATUS StatCode;
EFI_EVENT TimeoutEvent;
UINT32 IntStatus;
VOID *TxBuf;
//
//
//
CallbackPtr = Private->EfiBc.Mode->MakeCallbacks ? Private->CallbackProtocolPtr->Callback : 0;
SnpPtr = Private->SimpleNetwork;
SnpModePtr = SnpPtr->Mode;
//
// clear prior interrupt status
//
StatCode = SnpPtr->GetStatus (SnpPtr, &IntStatus, 0);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_WARN,
"\nSendPacket() Exit #1 %xh (%r)",
StatCode,
StatCode)
);
return StatCode;
}
Private->DidTransmit = FALSE;
if (CallbackPtr != NULL) {
if (CallbackPtr (
Private->CallbackProtocolPtr,
Function,
FALSE,
(UINT32) PacketLen,
PacketPtr
) != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
DEBUG (
(EFI_D_WARN,
"\nSendPacket() Exit #2 %xh (%r)",
EFI_ABORTED,
EFI_ABORTED)
);
return EFI_ABORTED;
}
}
//
// put packet in transmit queue
// headersize should be zero if not filled in
//
StatCode = gBS->CreateEvent (
EFI_EVENT_TIMER,
EFI_TPL_CALLBACK,
NULL,
NULL,
&TimeoutEvent
);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_ERROR,
"Could not create transmit timeout event. %r\n",
StatCode)
);
return EFI_DEVICE_ERROR;
}
//
// 5 milliseconds
//
StatCode = gBS->SetTimer (
TimeoutEvent,
TimerRelative,
50000
);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_ERROR,
"Could not set transmit timeout event timer. %r\n",
StatCode)
);
gBS->CloseEvent (TimeoutEvent);
return EFI_DEVICE_ERROR;
}
for (;;) {
StatCode = SnpPtr->Transmit (
SnpPtr,
(UINTN) SnpPtr->Mode->MediaHeaderSize,
(UINTN) (PacketLen + SnpPtr->Mode->MediaHeaderSize),
HeaderPtr,
&SnpModePtr->CurrentAddress,
(EFI_MAC_ADDRESS *) HardwareAddr,
&MediaProtocol
);
if (StatCode != EFI_NOT_READY) {
break;
}
if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
StatCode = EFI_TIMEOUT;
break;
}
}
gBS->CloseEvent (TimeoutEvent);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_WARN,
"\nSendPacket() Exit #3 %xh (%r)",
StatCode,
StatCode)
);
return StatCode;
}
//
// remove transmit buffer from snp's unused queue
// done this way in case someday things are buffered and we don't get it back
// immediately
//
StatCode = gBS->CreateEvent (
EFI_EVENT_TIMER,
EFI_TPL_CALLBACK,
NULL,
NULL,
&TimeoutEvent
);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_ERROR,
"Could not create transmit status timeout event. %r\n",
StatCode)
);
return EFI_DEVICE_ERROR;
}
//
// 5 milliseconds
//
StatCode = gBS->SetTimer (
TimeoutEvent,
TimerRelative,
50000
);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_ERROR,
"Could not set transmit status timeout event timer. %r\n",
StatCode)
);
gBS->CloseEvent (TimeoutEvent);
return EFI_DEVICE_ERROR;
}
for (;;) {
StatCode = SnpPtr->GetStatus (SnpPtr, &IntStatus, &TxBuf);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_WARN,
"\nSendPacket() Exit #4 %xh (%r)",
StatCode,
StatCode)
);
break;
}
if (IntStatus & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT) {
Private->DidTransmit = TRUE;
}
if (TxBuf != NULL) {
break;
}
if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
StatCode = EFI_TIMEOUT;
break;
}
}
gBS->CloseEvent (TimeoutEvent);
return StatCode;
}
//
//
//
EFI_BIS_PROTOCOL *
PxebcBisStart (
IN PXE_BASECODE_DEVICE *Private,
OUT BIS_APPLICATION_HANDLE *BisAppHandle,
OUT OPTIONAL EFI_BIS_DATA **BisDataSigInfo
)
/*++
Routine description:
Locate BIS interface and if found, try to start it.
Parameters:
Private := Pointer to PxeBc protocol
BisAppHandle := Pointer to BIS application handle storage
BisDataSigInfo := Pointer to BIS signature information storage
Returns:
--*/
{
EFI_STATUS EfiStatus;
EFI_HANDLE BisHandleBuffer;
UINTN BisHandleCount;
EFI_BIS_PROTOCOL *BisPtr;
EFI_BIS_VERSION BisInterfaceVersion;
BOOLEAN BisCheckFlag;
BisHandleCount = sizeof (EFI_HANDLE);
BisCheckFlag = FALSE;
//
// Locate BIS protocol handle (if present).
// If BIS protocol handle is not found, return NULL.
//
DEBUG ((EFI_D_INFO, "\ngBS->LocateHandle() "));
EfiStatus = gBS->LocateHandle (
ByProtocol,
&gEfiBisProtocolGuid,
NULL,
&BisHandleCount,
&BisHandleBuffer
);
if (EFI_ERROR (EfiStatus)) {
//
// Any error means that there is no BIS.
// Note - It could mean that there are more than
// one BIS protocols installed, but that scenario
// is not yet supported.
//
DEBUG (
(EFI_D_WARN,
"\nPxebcBisStart()""\n gBS->LocateHandle() %r (%xh)\n",
EfiStatus,
EfiStatus)
);
return NULL;
}
if (BisHandleCount != sizeof BisHandleBuffer) {
//
// This really should never happen, but I am paranoid.
//
DEBUG (
(EFI_D_NET,
"\nPxebcBisStart() BisHandleCount != %d\n",
sizeof BisHandleBuffer)
);
return NULL;
}
DEBUG ((EFI_D_INFO, "BIS handle found."));
//
// Locate BIS protocol interface.
// If the BIS protocol interface cannot be found, return NULL.
//
DEBUG ((EFI_D_INFO, "\ngBS->HandleProtocol() "));
EfiStatus = gBS->HandleProtocol (
BisHandleBuffer,
&gEfiBisProtocolGuid,
&BisPtr
);
if (EFI_ERROR (EfiStatus)) {
DEBUG (
(EFI_D_WARN,
"\nPxebcBisStart()""\n gBS->HandleProtocol() %r (%xh)\n",
EfiStatus,
EfiStatus)
);
return NULL;
}
if (BisPtr == NULL) {
//
// This really should never happen.
//
DEBUG (
(EFI_D_NET,
"\nPxebcBisStart()""\n gBS->HandleProtocoL() ""BIS protocol interface pointer is NULL!\n")
);
return NULL;
}
DEBUG ((EFI_D_INFO, "BIS protocol interface found."));
//
// Check BIS protocol revision.
// If the protocol revision is not recognized and supported by
// this PXE BaseCode revision, return FALSE.
//
switch (BisPtr->Revision) {
case 0: /* special case */
//
// Early revisions of the BIS protocol returned zero.
// Fall through to 0x10000.
//
case 0x10000:
DEBUG (
(EFI_D_INFO,
"\nPxebcBisStart()""\n BisPtr->Revision: %xh",
BisPtr->Revision)
);
break;
default:
DEBUG (
(EFI_D_NET,
"\nPxebcBisStart()""\nUnsupported BIS revision: %xh\n",
BisPtr->Revision)
);
return NULL;
}
//
// Check that all of the BIS API function pointers are not NULL.
//
if (BisPtr->Initialize == NULL ||
BisPtr->Shutdown == NULL ||
BisPtr->Free == NULL ||
BisPtr->GetBootObjectAuthorizationCertificate == NULL ||
BisPtr->GetBootObjectAuthorizationCheckFlag == NULL ||
BisPtr->GetBootObjectAuthorizationUpdateToken == NULL ||
BisPtr->GetSignatureInfo == NULL ||
BisPtr->UpdateBootObjectAuthorization == NULL ||
BisPtr->VerifyBootObject == NULL ||
BisPtr->VerifyObjectWithCredential == NULL
) {
DEBUG (
(
EFI_D_NET,
"\nPxebcBisStart()""\n BIS protocol interface is invalid."
"\n At least one BIS protocol function pointer is NULL.\n"
)
);
return NULL;
}
//
// Initialize BIS.
// If BIS does not initialize, return NULL.
//
DEBUG ((EFI_D_INFO, "\nBisPtr->Initialize() "));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?