bc.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,547 行 · 第 1/5 页
C
2,547 行
/*++
Copyright (c) 2004 - 2005, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
bc.c
Abstract:
--*/
#include "bc.h"
//
//
//
EFI_STATUS
EFIAPI
PxeBcDriverSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PxeBcDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PxeBcDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
extern
VOID
InitArpHeader (
VOID
);
extern
VOID
OptionsStrucInit (
VOID
);
//
// helper routines
//
VOID
CvtNum (
IN UINTN Number,
IN UINT8 *Buffer,
IN INTN Length
)
/*++
Routine Description:
Convert number to ASCII value
Arguments:
Number - Numeric value to convert to decimal ASCII value.
Buffer - Buffer to place ASCII version of the Number
Length - Length of Buffer.
Returns:
none - none
--*/
{
UINTN Remainder;
while (Length--) {
Remainder = Number % 10;
Number /= 10;
Buffer[Length] = (UINT8) ('0' + Remainder);
}
}
VOID
UtoA10 (
IN UINTN Number,
IN UINT8 *Buffer
)
/*++
Routine Description:
Convert number to decimal ASCII value at Buffer location
Arguments:
Number - Numeric value to convert to decimal ASCII value.
Buffer - Buffer to place ASCII version of the Number
Returns:
none - none
--*/
{
INTN Index;
UINT8 BuffArray[31];
BuffArray[30] = 0;
CvtNum (Number, BuffArray, 30);
for (Index = 0; Index < 30; ++Index) {
if (BuffArray[Index] != '0') {
break;
}
}
EfiCopyMem (Buffer, BuffArray + Index, 31 - Index);
}
UINTN
AtoU (
IN UINT8 *Buffer
)
/*++
Routine Description:
Convert ASCII numeric string to a UINTN value
Arguments:
Number - Numeric value to convert to decimal ASCII value.
Buffer - Buffer to place ASCII version of the Number
Returns:
Value - UINTN value of the ASCII string.
--*/
{
UINTN Value;
INT8 Character;
Value = 0;
Character = *Buffer++;
do {
Value = Value * 10 + Character - '0';
Character = *Buffer++;
} while (Character);
return Value;
}
UINT64
AtoU64 (
IN UINT8 *Buffer
)
/*++
Routine Description:
Convert ASCII numeric string to a UINTN value
Arguments:
Number - Numeric value to convert to decimal ASCII value.
Buffer - Buffer to place ASCII version of the Number
Returns:
Value - UINTN value of the ASCII string.
--*/
{
UINT64 Value;
UINT8 Character;
Value = 0;
while ((Character = *Buffer++) != '\0') {
Value = MultU64x32 (Value, 10) + (Character - '0');
}
return Value;
}
//
// random number generator
//
#define RANDOM_MULTIPLIER 2053
#define RANDOM_ADD_IN_VALUE 19
VOID
SeedRandom (
IN PXE_BASECODE_DEVICE *Private,
IN UINT16 InitialSeed
)
/*++
Routine Description:
Initialize the Seed for the random number generator
Arguments:
Returns:
none -
--*/
{
if (Private != NULL) {
Private->RandomSeed = InitialSeed;
}
}
UINT16
Random (
IN PXE_BASECODE_DEVICE *Private
)
/*++
Routine Description:
Generate and return a pseudo-random number
Arguments:
Returns:
Number - UINT16 random number
--*/
{
UINTN Number;
if (Private != NULL) {
Number = -(INTN) Private->RandomSeed * RANDOM_MULTIPLIER + RANDOM_ADD_IN_VALUE;
return Private->RandomSeed = (UINT16) Number;
} else {
return 0;
}
}
//
// calculate the internet checksum (RFC 1071)
// return 16 bit ones complement of ones complement sum of 16 bit words
//
UINT16
IpChecksum (
IN UINT16 *Packet,
IN UINTN Length
)
/*++
Routine Description:
Calculate the internet checksum (see RFC 1071)
Arguments:
Packet - Buffer which contains the data to be checksummed
Length - Length to be checksummed
Returns:
Checksum - Returns the 16 bit ones complement of
ones complement sum of 16 bit words
--*/
{
UINT32 Sum;
UINT8 Odd;
Sum = 0;
Odd = (UINT8) (Length & 1);
Length >>= 1;
while (Length--) {
Sum += *Packet++;
}
if (Odd) {
Sum += *(UINT8 *) Packet;
}
Sum = (Sum & 0xffff) + (Sum >> 16);
//
// in case above carried
//
Sum += Sum >> 16;
return (UINT16) (~ (UINT16) Sum);
}
UINT16
IpChecksum2 (
IN UINT16 *Header,
IN UINTN HeaderLen,
IN UINT16 *Message,
IN UINTN MessageLen
)
/*++
Routine Description:
Calculate the internet checksum (see RFC 1071)
on a non contiguous header and data
Arguments:
Header - Buffer which contains the data to be checksummed
HeaderLen - Length to be checksummed
Message - Buffer which contains the data to be checksummed
MessageLen - Length to be checksummed
Returns:
Checksum - Returns the 16 bit ones complement of
ones complement sum of 16 bit words
--*/
{
UINT32 Sum;
Sum = (UINT16)~IpChecksum (Header, HeaderLen) + (UINT16)~IpChecksum (Message, MessageLen);
//
// in case above carried
//
Sum += Sum >> 16;
return (UINT16) (~ (UINT16) Sum);
}
UINT16
UpdateChecksum (
IN UINT16 OldChksum,
IN UINT16 OldWord,
IN UINT16 NewWord
)
/*++
Routine Description:
Adjust the internet checksum (see RFC 1071) on a single word update.
Arguments:
OldChkSum - Checksum previously calculated
OldWord - Value
NewWord - New Value
Returns:
Checksum - Returns the 16 bit ones complement of
ones complement sum of 16 bit words
--*/
{
UINT32 sum;
sum = ~OldChksum + NewWord - OldWord;
//
// in case above carried
//
sum += sum >> 16;
return (UINT16) (~ (UINT16) sum);
}
STATIC
BOOLEAN
SetMakeCallback (
IN PXE_BASECODE_DEVICE *Private
)
/*++
Routine Description:
See if a callback is in play
Arguments:
Private - Pointer to Pxe BaseCode Protocol
Returns:
0 - Callbacks are active on the handle
1 - Callbacks are not active on the handle
--*/
{
Private->EfiBc.Mode->MakeCallbacks = (BOOLEAN) (gBS->HandleProtocol (
Private->Handle,
&gEfiPxeBaseCodeCallbackProtocolGuid,
(VOID *) &Private->CallbackProtocolPtr
) == EFI_SUCCESS);
DEBUG (
(EFI_D_INFO,
"\nMode->MakeCallbacks == %d ",
Private->EfiBc.Mode->MakeCallbacks)
);
DEBUG (
(EFI_D_INFO,
"\nPrivate->CallbackProtocolPtr == %xh ",
Private->CallbackProtocolPtr)
);
if (Private->CallbackProtocolPtr != NULL) {
DEBUG (
(EFI_D_INFO,
"\nCallbackProtocolPtr->Revision = %xh ",
Private->CallbackProtocolPtr->Revision)
);
DEBUG (
(EFI_D_INFO,
"\nCallbackProtocolPtr->Callback = %xh ",
Private->CallbackProtocolPtr->Callback)
);
}
return Private->EfiBc.Mode->MakeCallbacks;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
WaitForReceive (
IN PXE_BASECODE_DEVICE *Private,
IN EFI_PXE_BASE_CODE_FUNCTION Function,
IN EFI_EVENT TimeoutEvent,
IN OUT UINTN *HeaderSizePtr,
IN OUT UINTN *BufferSizePtr,
IN OUT UINT16 *ProtocolPtr
)
/*++
Routine Description:
Routine which does an SNP->Receive over a timeout period and doing callbacks
Arguments:
Private - Pointer to Pxe BaseCode Protocol
Function - What PXE function to callback
TimeoutEvent - Timer event that will trigger when we have waited too
long for an incoming packet
HeaderSizePtr - Pointer to the size of the Header size
BufferSizePtr - Pointer to the size of the Buffer size
ProtocolPtr - The protocol to sniff for (namely, UDP/TCP/etc)
Returns:
0 - Something was returned
!0 - Like there was nothing to receive (EFI_TIMEOUT/NOT_READY)
--*/
{
EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;
EFI_PXE_CALLBACK CallbackPtr;
EFI_STATUS StatCode;
EFI_EVENT CallbackEvent;
//
// Initialize pointer to SNP interface
//
SnpPtr = Private->SimpleNetwork;
//
// Initialize pointer to PxeBc callback routine - if any
//
CallbackPtr = (Private->EfiBc.Mode->MakeCallbacks) ? Private->CallbackProtocolPtr->Callback : NULL;
//
// Create callback event and set timer
//
StatCode = gBS->CreateEvent (
EFI_EVENT_TIMER,
EFI_TPL_CALLBACK,
NULL,
NULL,
&CallbackEvent
);
if (EFI_ERROR (StatCode)) {
return EFI_DEVICE_ERROR;
}
//
// every 100 milliseconds
//
StatCode = gBS->SetTimer (
CallbackEvent,
TimerPeriodic,
1000000
);
if (EFI_ERROR (StatCode)) {
gBS->CloseEvent (CallbackEvent);
return EFI_DEVICE_ERROR;
}
//
// Loop until a packet is received or a receive error is detected or
// a callback abort is detected or a timeout event occurs.
//
for (;;)
{
#if 0
//
// Check for received packet event.
//
if (!EFI_ERROR (gBS->CheckEvent (SnpPtr->WaitForPacket))) {
//
// Packet should be available. Attempt to read it.
//
*BufferSizePtr = BUFFER_ALLOCATE_SIZE;
StatCode = SnpPtr->Receive (
SnpPtr,
HeaderSizePtr,
BufferSizePtr,
Private->ReceiveBufferPtr,
0,
0,
ProtocolPtr
);
if (EFI_ERROR (StatCode)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?