bc.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,547 行 · 第 1/5 页

C
2,547
字号

  BisInterfaceVersion.Major = BIS_VERSION_1;

  EfiStatus = BisPtr->Initialize (
                        BisPtr,
                        BisAppHandle,
                        &BisInterfaceVersion,
                        NULL
                        );

  if (EFI_ERROR (EfiStatus)) {
    DEBUG (
      (EFI_D_WARN,
      "\nPxebcBisStart()""\n  BisPtr->Initialize()  %r (%xh)\n",
      EfiStatus,
      EfiStatus)
      );

    return NULL;
  }

  DEBUG (
    (EFI_D_INFO,
    "  BIS version: %d.%d",
    BisInterfaceVersion.Major,
    BisInterfaceVersion.Minor)
    );

  //
  // If the requested BIS API version is not supported,
  // shutdown BIS and return NULL.
  //
  if (BisInterfaceVersion.Major != BIS_VERSION_1) {
    DEBUG (
      (EFI_D_WARN,
      "\nPxebcBisStart()""\n  BIS version %d.%d not supported by PXE BaseCode.\n",
      BisInterfaceVersion.Major,
      BisInterfaceVersion.Minor)
      );

    BisPtr->Shutdown (*BisAppHandle);
    return NULL;
  }
  //
  // Get BIS check flag.
  // If the BIS check flag cannot be read, shutdown BIS and return NULL.
  //
  DEBUG ((EFI_D_INFO, "\nBisPtr->GetBootObjectAuthorizationCheckFlag()  "));

  EfiStatus = BisPtr->GetBootObjectAuthorizationCheckFlag (*BisAppHandle, &BisCheckFlag);

  if (EFI_ERROR (EfiStatus)) {
    DEBUG (
      (EFI_D_WARN,
      "\nPxebcBisStart()""\n  BisPtr->GetBootObjectAuthorizationCheckFlag()  %r (%xh)\n",
      EfiStatus,
      EfiStatus)
      );

    BisPtr->Shutdown (*BisAppHandle);
    return NULL;
  }
  //
  // If the BIS check flag is FALSE, shutdown BIS and return NULL.
  //
  if (!BisCheckFlag) {
    DEBUG ((EFI_D_INFO, "\nBIS check flag is FALSE.\n"));
    BisPtr->Shutdown (*BisAppHandle);
    return NULL;
  } else {
    DEBUG ((EFI_D_INFO, "\nBIS check flag is TRUE."));
  }
  //
  // Early out if caller does not want signature information.
  //
  if (BisDataSigInfo == NULL) {
    return BisPtr;
  }
  //
  // Get BIS signature information.
  // If the signature information cannot be read or is invalid,
  // shutdown BIS and return NULL.
  //
  DEBUG ((EFI_D_INFO, "\nBisPtr->GetSignatureInfo()  "));

  EfiStatus = BisPtr->GetSignatureInfo (*BisAppHandle, BisDataSigInfo);

  if (EFI_ERROR (EfiStatus)) {
    DEBUG (
      (EFI_D_WARN,
      "\nPxebcBisStart()""\n  BisPtr_GetSignatureInfo()  %r (%xh)\n",
      EfiStatus,
      EfiStatus)
      );

    BisPtr->Shutdown (*BisAppHandle);
    return NULL;
  }

  if (*BisDataSigInfo == NULL) {
    //
    // This should never happen.
    //
    DEBUG (
      (EFI_D_NET,
      "\nPxebcBisStart()""\n  BisPtr->GetSignatureInfo()  Data pointer is NULL!\n")
      );

    BisPtr->Shutdown (*BisAppHandle);
    return NULL;
  }

  if ((*BisDataSigInfo)->Length < sizeof (EFI_BIS_SIGNATURE_INFO) ||
      (*BisDataSigInfo)->Length % sizeof (EFI_BIS_SIGNATURE_INFO) ||
      (*BisDataSigInfo)->Length > sizeof (EFI_BIS_SIGNATURE_INFO) * 63
      ) {
    //
    // This should never happen.
    //
    DEBUG (
      (EFI_D_NET,
      "\nPxebcBisStart()""\n  BisPtr->GetSignatureInfo()  Invalid BIS siginfo length.\n")
      );

    BisPtr->Free (*BisAppHandle, *BisDataSigInfo);
    BisPtr->Shutdown (*BisAppHandle);
    return NULL;
  }

  return BisPtr;
}

VOID
PxebcBisStop (
  EFI_BIS_PROTOCOL        *BisPtr,
  BIS_APPLICATION_HANDLE  BisAppHandle,
  EFI_BIS_DATA            *BisDataSigInfo
  )
/*++
Routine description:
  Stop the BIS interface and release allocations.

Parameters:
  BisPtr := Pointer to BIS interface
  BisAppHandle := BIS application handle
  BisDataSigInfo := Pointer to BIS signature information data

Returns:

--*/
{
  if (BisPtr == NULL) {
    return ;
  }
  //
  // Free BIS allocated resources and shutdown BIS.
  // Return TRUE - BIS support is officially detected.
  //
  if (BisDataSigInfo != NULL) {
    BisPtr->Free (BisAppHandle, BisDataSigInfo);
  }

  BisPtr->Shutdown (BisAppHandle);
}

BOOLEAN
PxebcBisVerify (
  PXE_BASECODE_DEVICE *Private,
  VOID                *FileBuffer,
  UINTN               FileLength,
  VOID                *CredentialBuffer,
  UINTN               CredentialLength
  )
/*++
Routine description:
  Verify image and credential file.

Parameters:
  Private := Pointer to PxeBc interface
  FileBuffer := Pointer to image buffer
  FileLength := Image length in bytes
  CredentialBuffer := Pointer to credential buffer
  CredentialLength := Credential length in bytes

Returns:
  TRUE := verified
  FALSE := not verified
--*/
{
  EFI_BIS_PROTOCOL        *BisPtr;
  BIS_APPLICATION_HANDLE  BisAppHandle;
  EFI_BIS_DATA            FileData;
  EFI_BIS_DATA            CredentialData;
  EFI_STATUS              EfiStatus;
  BOOLEAN                 IsVerified;

  if (Private == NULL || FileBuffer == NULL || FileLength == 0 || CredentialBuffer == NULL || CredentialLength == 0) {
    return FALSE;
  }

  BisPtr = PxebcBisStart (Private, &BisAppHandle, NULL);

  if (BisPtr == NULL) {
    return FALSE;
  }

  FileData.Length       = (UINT32) FileLength;
  FileData.Data         = FileBuffer;
  CredentialData.Length = (UINT32) CredentialLength;
  CredentialData.Data   = CredentialBuffer;

  EfiStatus = BisPtr->VerifyBootObject (
                        BisAppHandle,
                        &CredentialData,
                        &FileData,
                        &IsVerified
                        );

  PxebcBisStop (BisPtr, BisAppHandle, NULL);

  return (BOOLEAN) ((EFI_ERROR (EfiStatus)) ? FALSE : (IsVerified ? TRUE : FALSE));
}

BOOLEAN
PxebcBisDetect (
  PXE_BASECODE_DEVICE *Private
  )
/*++
Routine description:
  Check for BIS interface presence.

Parameters:
  Private := Pointer to PxeBc interface

Returns:
  TRUE := BIS present
  FALSE := BIS not present
--*/
{
  EFI_BIS_PROTOCOL        *BisPtr;
  BIS_APPLICATION_HANDLE  BisAppHandle;
  EFI_BIS_DATA            *BisDataSigInfo;

  BisPtr = PxebcBisStart (Private, &BisAppHandle, &BisDataSigInfo);

  if (BisPtr == NULL) {
    return FALSE;
  }

  PxebcBisStop (BisPtr, BisAppHandle, BisDataSigInfo);

  return TRUE;
}

static VOID *BCNotifyReg;

EFI_STATUS
EFIAPI
BcStart (
  IN EFI_PXE_BASE_CODE_PROTOCOL *This,
  IN BOOLEAN                    UseIPv6
  )
/*++

  Routine Description:
    Start and initialize the BaseCode protocol, Simple Network protocol and UNDI.

  Arguments:
    Private                - Pointer to Pxe BaseCode Protocol
    UseIPv6            - Do we want to support IPv6?

  Returns:
    EFI_SUCCESS
    EFI_INVALID_PARAMETER
    EFI_UNSUPPORTED
    EFI_ALREADY_STARTED
    EFI_OUT_OF_RESOURCES
    Status is also returned from SNP.Start() and SNP.Initialize().

--*/
{
  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;
  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;
  EFI_STATUS                  Status;
  EFI_STATUS                  StatCode;
  PXE_BASECODE_DEVICE         *Private;

  //
  // Lock the instance data
  //
  StatCode = EFI_SUCCESS;

  if (This == NULL) {
    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
    return EFI_INVALID_PARAMETER;
  }

  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

  if (Private == NULL) {
    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE pointer == NULL"));
    return EFI_INVALID_PARAMETER;
  }

  EfiAcquireLock (&Private->Lock);

  //
  // Make sure BaseCode is not already started.
  //
  if (This->Mode->Started) {
    DEBUG ((EFI_D_WARN, "\nBcStart()  BC is already started.\n"));
    EfiReleaseLock (&Private->Lock);
    return EFI_ALREADY_STARTED;
  }

#if !SUPPORT_IPV6
  //
  // Fail if IPv6 is requested and not supported.
  //
  if (UseIPv6) {
    DEBUG ((EFI_D_WARN, "\nBcStart()  IPv6 is not supported.\n"));
    EfiReleaseLock (&Private->Lock);
    return EFI_UNSUPPORTED;
  }
#endif
  //
  // Setup shortcuts to SNP protocol and data structure.
  //
  SnpPtr      = Private->SimpleNetwork;
  SnpModePtr  = SnpPtr->Mode;

  //
  // Start and initialize SNP.
  //
  if (SnpModePtr->State == EfiSimpleNetworkStopped) {
    StatCode = (*SnpPtr->Start) (SnpPtr);

    if (SnpModePtr->State != EfiSimpleNetworkStarted) {
      DEBUG ((EFI_D_WARN, "\nBcStart()  Could not start SNP.\n"));
      EfiReleaseLock (&Private->Lock);
      return StatCode;
    }
  }
  //
  // acquire memory for mode and transmit/receive buffers
  //
  if (SnpModePtr->State == EfiSimpleNetworkStarted) {
    StatCode = (*SnpPtr->Initialize) (SnpPtr, 0, 0);

    if (SnpModePtr->State != EfiSimpleNetworkInitialized) {
      DEBUG ((EFI_D_WARN, "\nBcStart()  Could not initialize SNP."));
      EfiReleaseLock (&Private->Lock);
      return StatCode;
    }
  }
  //
  // Dump debug info.
  //
  DEBUG ((EFI_D_INFO, "\nBC Start()"));
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->State                    %Xh",
    SnpModePtr->State)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->HwAddressSize            %Xh",
    SnpModePtr->HwAddressSize)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MediaHeaderSize          %Xh",
    SnpModePtr->MediaHeaderSize)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MaxPacketSize            %Xh",
    SnpModePtr->MaxPacketSize)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MacAddressChangeable     %Xh",
    SnpModePtr->MacAddressChangeable)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MultipleTxSupported      %Xh",
    SnpModePtr->MultipleTxSupported)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->CurrentAddress           %Xh",
    SnpModePtr->CurrentAddress)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->BroadcastAddress         %Xh",
    SnpModePtr->BroadcastAddress)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->PermanentAddress         %Xh",
    SnpModePtr->PermanentAddress)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->NvRamSize                %Xh",
    SnpModePtr->NvRamSize)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->NvRamAccessSize          %Xh",
    SnpModePtr->NvRamAccessSize)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->ReceiveFilterMask        %Xh",
    SnpModePtr->ReceiveFilterMask)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->ReceiveFilterSetting     %Xh",
    SnpModePtr->ReceiveFilterSetting)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MCastFilterCount         %Xh",
    SnpModePtr->MCastFilterCount)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MCastFilter              %Xh",
    SnpModePtr->MCastFilter)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->IfType                   %Xh",
    SnpModePtr->IfType)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MediaPresentSupported    %Xh",
    SnpModePtr->MediaPresentSupported)
    );
  DEBUG (
    (EFI_D_INFO,
    "\nSnpModePtr->MediaPresent             %Xh",
    SnpModePtr->MediaPresent)
    );

  //
  // If media check is supported and there is no media,
  // return error to caller.
  //
  if (SnpModePtr->MediaPresentSupported && !SnpModePtr->MediaPresent) {
    DEBUG ((EFI_D_WARN, "\nBcStart()  Media not present.\n"));
    EfiReleaseLock (&Private->Lock);
    return EFI_NO_MEDIA;
  }
  //
  // Allocate Tx/Rx buffers
  //
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  BUFFER_ALLOCATE_SIZE,
                  &Private->TransmitBufferPtr
                  );

  if (!EFI_ERROR (Status)) {
    EfiZeroMem (Private->TransmitBufferPtr, BUFFER_ALLOCATE_SIZE);
  } else {
    DEBUG ((EFI_D_NET, "\nBcStart()  Could not alloc TxBuf.\n"));
    EfiReleaseLock (&Private->Lock);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  BUFFER_ALLOCATE_SIZE,
                  &Private->ReceiveBufferPtr
                  );

  if (!EFI_ERROR (Status)) {
    EfiZeroMem (Private->ReceiveBufferPtr, BUFFER_ALLOCATE_SIZE);
  } else {
    DEBUG ((EFI_D_NET, "\nBcStart()  Could not alloc RxBuf.\n"));
    gBS->FreePool (Private->TransmitBufferPtr);
    EfiReleaseLock (&Private->Lock);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  256,
                  &Private->TftpErrorBuffer
                  );

  if (EFI_ERROR (Status)) {
    gBS->FreePool (Private->ReceiveBufferPtr);
    gBS->FreePool (Private->TransmitBufferPtr);
    EfiReleaseLock (&Private->Lock);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gBS->AllocatePool (EfiBootServicesData, 256, &Private->TftpAckBuffer);

  if (EFI_ERROR (Status)) {
    gBS->FreePool (Private->TftpErrorBuffer);
    gBS->FreePool (Private->ReceiveBufferPtr);
    gBS->FreePool (Private->TransmitBufferPtr);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?